我可以在我的 preinst 脚本中调用其他 dpkg 或 apt-* 命令吗?

我可以在我的 preinst 脚本中调用其他 dpkg 或 apt-* 命令吗?

作为将部署到 Ubuntu 12.04 设备的自定义(内部).deb 文件的一部分,我需要添加几个 PPA 存储库,运行 apt-get update,然后从这些 PPA 安装软件包。

可以在我的 .deb 文件中的 .preinst 或 .postinst 脚本中完成此操作吗?

我假设当我的 .deb 文件安装时(sudo dpkg -i testing.deb)可能存在一些锁或机制,阻止我调用某些命令,如add-apt-repositoryapt-get updateapt-get install

这是一个正确的假设吗?

答案1

你是对的。维护者脚本不应该对 apt 或 dpkg 状态进行任何更改,除了安装软件包时所做的更改。

不过,将文件安装到 中/etc/apt/sources.list.d是可以的。大多数充当“安装此软件包以将 APT 存储库 X 添加到您的系统”角色的软件包都只是这样做(而不是调用add-apt-repository)。将用于签署存储库的 GPG 公钥放入 中也很常见/etc/apt/trusted.gpg.d

如果您想让用户轻松执行软件的附加安装步骤,您可能只需要发送一个执行该作业的脚本,并告诉用户手动运行该脚本。

但是,如果您真的非常想自动调用apt-get updateapt-get install等,并且您不介意您的软件包在 Debian 或 Ubuntu 中完全不可接受,并且您的用户可以接受软件包的这种行为,那么您也许可以添加一些内容来/etc/cron.d检查是否存在任何 apt 或 dpkg 锁,如果没有,则执行您的其他安装步骤并安排不再执行这些步骤。我不推荐这种方法。

答案2

是的,您不应该这样做——但如果必须这样做——您可以按照以下方法apt-get从脚本内部调用。直接preinst调用也可以使用相同的方法。dpkg

这个想法是启动一个子shell,它在后台耐心等待,直到所有安装活动结束,然后执行其操作。

((
   # wait for install to finish
   while pgrep -x 'dpkg|apt|apt-get' > /dev/null; do sleep 1; done
   export DEBIAN_FRONTEND=noninteractive
   # make sure no one else is locking the dpkg database
   flock --exclusive --close /var/lib/dpkg/lock \
       apt-get install --assume-yes my-fancy-package
) 2>&1 >/dev/null </dev/null &)

显然,如果有多个软件包尝试此技巧,则会导致问题。所以正如我上面所说,你真的不应该这样做。

相关内容