作为将部署到 Ubuntu 12.04 设备的自定义(内部).deb 文件的一部分,我需要添加几个 PPA 存储库,运行 apt-get update,然后从这些 PPA 安装软件包。
可以在我的 .deb 文件中的 .preinst 或 .postinst 脚本中完成此操作吗?
我假设当我的 .deb 文件安装时(sudo dpkg -i testing.deb
)可能存在一些锁或机制,阻止我调用某些命令,如add-apt-repository
、apt-get update
和apt-get install
。
这是一个正确的假设吗?
答案1
你是对的。维护者脚本不应该对 apt 或 dpkg 状态进行任何更改,除了安装软件包时所做的更改。
不过,将文件安装到 中/etc/apt/sources.list.d
是可以的。大多数充当“安装此软件包以将 APT 存储库 X 添加到您的系统”角色的软件包都只是这样做(而不是调用add-apt-repository
)。将用于签署存储库的 GPG 公钥放入 中也很常见/etc/apt/trusted.gpg.d
。
如果您想让用户轻松执行软件的附加安装步骤,您可能只需要发送一个执行该作业的脚本,并告诉用户手动运行该脚本。
但是,如果您真的非常想自动调用apt-get update
或apt-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 &)
显然,如果有多个软件包尝试此技巧,则会导致问题。所以正如我上面所说,你真的不应该这样做。