如何仅在首次安装软件包和升级期间运行脚本?


14

我最近开始打包一些软件并将其发布在Launchpad上。安装和删除工作正常,但是将软件包从一个版本升级到另一个版本是有问题的。

问题在于,有些脚本仅在首次安装软件包时才需要运行。这些脚本填充数据库,创建用户等。它们当前在package.postinst configure)部分中被调用。然而,这导致他们在升级过程中被称为以及所示的图

有没有一种方法可以在.deb程序包中包含仅在首次安装程序包时执行,而不在升级过程中执行的维护程序脚本?还是在.deb程序包中包含一些初始设置脚本的优美方法是什么?

Answers:


15

使用debian/preinst文件,您可以在安装时执行操作,但不能执行升级操作。

#!/bin/sh
set -e

case "$1" in
    install)
        # do some magic
        ;;

    upgrade|abort-upgrade)
        ;;

    *)
        echo "postinst called with unknown argument \`$1'" >&2
        exit 0
        ;;
esac

#DEBHELPER#

exit 0

尽管顾名思义,它是在安装软件包之前运行的。因此,您可能无法在此处执行所需的操作。大多数软件包只是在配置阶段测试postinst用户是否已经创建。这是colord

$ cat  /var/lib/dpkg/info/colord.postinst
#!/bin/sh

set -e

case "$1" in
    configure)

# create colord group if it isn't already there
    if ! getent group colord >/dev/null; then
            addgroup --quiet --system colord
    fi

# create the scanner group if it isn't already there
    if ! getent group scanner >/dev/null; then
        addgroup --quiet --system scanner
    fi

# create colord user if it isn't already there
    if ! getent passwd colord >/dev/null; then
            adduser --system --ingroup colord --home /var/lib/colord colord \
        --gecos "colord colour management daemon"
        # Add colord user to scanner group
        adduser --quiet colord scanner
    fi

# ensure /var/lib/colord has appropriate permissions
    chown -R colord:colord /var/lib/colord

    ;;
esac    



exit 0

28

Debian Wiki上查看以下图表,了解如何调用维护者脚本: Debian维护者脚本流程图

如果您沿左手操作(“一切正常”路径),您会看到该postinst脚本是使用最新配置的版本调用的。这使您有机会区分升级和全新安装-在升级的情况下,您的postinst将被称为

postinst configure 1.23-0ubuntu1

1.23-0ubuntu1软件包的先前安装版本在哪里,而对于全新安装,它将被称为

postinst configure

这也使您可以处理从特定版本升级时需要执行操作的情况-您可以签入该postinst版本。

这样可以很容易地检查脚本是在“安装”还是在“升级”上完成的。如果$ 2为空,则为安装。所以:

if [ -z "$2" ]; then
  do install stuff
else
  do upgrade stuff
fi

1
请注意,如果您已删除软件包(但未清除)并再次安装,则还会传递额外的参数。
凌晨

3

您可能可以将debian / preinst脚本与postinst结合使用。

在preinst脚本中,检查pkg肯定安装的文件。如果存在,则什么也不做(因为您的软件包先前已安装),否则,请执行设置步骤。

如果设置步骤要求安装pkg(在这种情况下,由于preinst在安装之前运行,上述操作将不起作用),则preinst脚本可以编写一个文件,例如:/ tmp / setupmypkg。您的postinst脚本可以简单地测试该文件是否存在,如果存在,则执行以下两项操作:

  • 您的初始设置步骤
  • 删除/ tmp / setupmypkg文件

1
是的,这可以工作,我目前正在做类似的事情。但是它看起来还是有点笨拙……我希望能有更多的本机方法。似乎不是这样的异国情调的请求吧?
Jeroen

1

我发现如果您之前已经安装过软件包,然后卸载了该软件包(但未清除),然后尝试重新安装,则在“ postinst configure”脚本中测试$ 2不能正常工作。在这种情况下,postinst脚本仍将为“ postinst configure”步骤获取版本参数。

但是,如果您以前安装过该软件包,然后删除并清除它,然后再次重新安装,则“ postinst configure”脚本将不会在$ 2中获得版本参数。


0

我不这么认为,但是您可以轻松地修改preinst / postinst脚本,以检查是否是首次安装软件包并采取标准措施。

可能是这样的

在preinst。

if not is_package_istalled():
    export MY_PACKAGE_FIRST_INSTALL

在发布后,

if MY_PACKAGE_FIRST_INSTALL:
    Do First Install Setup 

编辑

嗯,也许您可​​以直接在postinst中检查所有这一切,因为我认为dpkg不会在执行postinst之前将软件包的状态设置为已安装,但我不确定。所以以上可能会出现

在发布后,

if not is_package_istalled():
    Do First Install Setup 

is_package_installed可以用来检测安装状态。可能类似于“ dpkg --status软件包名称”

要么

为什么不只是简单地检查您要进行的更改是否已经存在,而如果未进行则仅继续进行。


我不明白 IS_INSTALLED来自哪里?
Jeroen

没有IS_INSTALLED,它只是伪代码。只是一个例子。IS_INSTALLED可能是“ dpkg --status package_name”之类的命令的输出,我的意思是,您可以检查软件包是否安装在preinst中,设置状态var,然后根据此状态var在postinst中采取措施。
Owais Lone 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.