可靠地检查软件包是否已安装


20

我有一个简单的要求。我想定义几个变量,这些变量将与要通过shell脚本安装的任何给定软件包相对应。

下面的示例代码:

MISC="shutter pidgin"
WEB="apache2 mongodb"

for pkg in $MISC $WEB; do
    if [ "dpkg-query -W $pkg | awk {'print $1'} = """ ]; then
        echo -e "$pkg is already installed"
    else
        apt-get -qq install $pkg
        echo "Successfully installed $pkg"
    fi
done

一切都可以用,但是逻辑似乎有缺陷,因为它不能可靠地安装我想要的软件包。它说已经安装了它们,或者正在尝试安装以前已经安装的软件包。

我也在尝试command -v以下方法:

if [ "dpkg -l | awk {'print $2'} | grep --regexp=^$pkg$ != """ ]; then

甚至使用-n-z标志来检查返回的字符串是否为空。可以肯定的是,我在这里缺少一些很好的认识。

您是否知道该怎么做才能确保确实安装了软件包?

谢谢!


如果您还要求apt-get install安装软件包,有什么害处?您可以致电apt-get install $MISC $WEB
jarno 2015年

Answers:


15

从本质上讲,你只需要更换if与条件

if dpkg --get-selections | grep -q "^$pkg[[:space:]]*install$" >/dev/null; then

无法使用dpkg-query,因为对于已删除但尚未清除的软件包,它也返回true。

我也建议apt-get在给出成功消息之前检查的退出代码:

if apt-get -qq install $pkg; then
    echo "Successfully installed $pkg"
else
    echo "Error installing $pkg"
fi

怎么&>办?
塔蒙(Taymon)2013年

@Taymon:将stdin和stderr都重定向到给定的文件(/dev/null在这种情况下),因为我们不需要输出,只需要退出代码。只能在bash(必须在脚本的第一行中#!/bin/bash)使用,否则请使用>/dev/null 2>&1
enzotib

@Taymon:我更改了逻辑,因为我发现上述解决方案中存在缺陷。
enzotib

注意:如果使用bash并设置了pipefail选项,则grep -q会生成Heisenbugs。基本上,grep在dpkg完成写入之前退出(在这种情况下,您希望退出状态为0),因此dpkg无法写入管道(而是生成非0退出状态)。确保没有设置pipefail,或者放弃“ -q”选项的效率提升(可能很小)。
罗恩·伯克

2

您可以通过dpkg-query对其进行测试:

if dpkg-query -W -f'${Status}' "$pkg" 2>/dev/null | grep -q "ok installed"; then

注意*和?是通配符(如果它们出现在$ pkg中)。我猜想dpkg-query可能会打印“需要重新安装”,而不是“确定已安装”,如果软件包已损坏并且需要通过命令重新安装,该命令apt-get install --reinstall也可以用于安装新软件包。


0
#to check package is installed or not without distribution dependency
#!/bin/bash
read -p "Package Name: " pkg
which $pkg > /dev/null 2>&1
if [ $? == 0 ]
then
echo "$pkg is already installed. "
else
read -p "$pkg is not installed. Answer yes/no if want installation_ " request
if  [ $request == "yes" ]
then
yum install $pkg
fi
fi
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.