Bash - 如何检查软件包是否可以安装,是否正在运行apt-get/dpkg?

7
在一个bash脚本中,我想要安装一个软件包。在这样做之前,我需要检查是否已经有其他的apt-get或者dpkg实例正在运行。如果是这种情况,apt-get会失败,因为它已经被锁定了。
检查/var/lib/dpkg/lock/var/lib/apt/lists/lock是否存在,如果两者都不存在,那么安装是安全的吗?
4个回答

2

这取决于您想要如何处理apt-get错误。 对于您的需求,检查/var/lib/dpkg/lock/var/lib/apt/lists/lock是可以的,但如果您想要更加谨慎,您可以进行模拟并检查返回代码,例如:

if sudo apt-get --simulate install packageThatDoesntExist      
then echo "we're good"
else echo "oops, something happened"
fi

例如,这将会给出:
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package packageThatDoesntExist
oops, something happened

编辑:--simulate不会检查锁定,因此您可能希望在那里进行额外的检查。如果您想单独检查sudo,则还可以删除sudo


2

仅检查锁定文件是不够可靠的。也许你真正想要做的是检查 dpkg 数据库是否被锁定。我使用以下方法进行检查:

## check if DPKG database is locked
dpkg -i /dev/zero 2>/dev/null
if [ "$?" -eq 2 ]; then
    echo "E: dpkg database is locked."
fi

希望有更好的方法...
此外,我还进行以下检查,因为如果存在损坏的软件包等问题,安装可能是不安全的:

apt-get check >/dev/null 2>&1
if [ "$?" -ne 0 ]; then
    echo "E: \`apt-get check\` failed, you may have broken packages. Aborting..."
fi

不确定为什么,但是在虚拟机上,lsof和fuser都无法正常工作(两者都没有输出任何内容,并且无论如何都返回1)。这个解决方案救了我。 - kael
这段代码很危险,因为它容易受到TOCTOU攻击的影响。 - Guillem Jover

2
在目前的稳定版Debian Wheezy中,这些文件始终存在。因此,我发现使用lsof /var/lib/dpkg/lock更有用。如果没有任何进程正在使用锁,则返回1,如果有,则返回0,因此:
lsof /var/lib/dpkg/lock >/dev/null 2>&1
[ $? = 0 ] && echo "dpkg lock in use"

别忘了 - 这需要在sudo或root帐户下运行。 - norekhov

2
您可以简单地检查apt-get或dpkg是否正在运行:
ps -C apt-get,dpkg >/dev/null && echo "installing software" || echo "all clear"

这种方法的潜在缺陷是有许多可能锁定apt的应用程序。从Ubuntu 16.04开始,apt是首选命令,而您的测试无法捕获此问题。跟上可能的前端可能会证明是一件头疼的事情。 - David Baucum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接