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

van*_*anz 23 scripts

我有一个简单的要求。我想定义几个变量,这些变量将对应于我想通过 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
Run Code Online (Sandbox Code Playgroud)

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

我也一直在尝试command -v或以下内容:

if [ "dpkg -l | awk {'print $2'} | grep --regexp=^$pkg$ != """ ]; then
Run Code Online (Sandbox Code Playgroud)

即使使用-n-z标志来检查返回的字符串是否为空。很确定我在这里错过了一些很好的意义。

您知道我可以做些什么来确保实际安装了软件包吗?

谢谢!

enz*_*tib 18

本质上,您只需要将if条件替换为

if dpkg --get-selections | grep -q "^$pkg[[:space:]]*install$" >/dev/null; then
Run Code Online (Sandbox Code Playgroud)

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

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

if apt-get -qq install $pkg; then
    echo "Successfully installed $pkg"
else
    echo "Error installing $pkg"
fi
Run Code Online (Sandbox Code Playgroud)


jar*_*rno 5

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

if dpkg-query -W -f'${Status}' "$pkg" 2>/dev/null | grep -q "ok installed"; then
Run Code Online (Sandbox Code Playgroud)

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