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

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

我有一个简单的需求。我想定义几个变量,这些变量将对应于我想通过 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标志来检查返回的字符串是否为空。我确信我在这里缺少了一些良好的判断力。

您知道我该怎么做才能确保软件包是否真正安装?

谢谢!

答案1

本质上你只需要用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

答案2

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

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

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

答案3

#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

答案4

这看起来与 OP 想要做的类似,所以我想分享一下:

function package_check() {
    # Tell apt-get we're never going to be able to give manual feedback:
    export DEBIAN_FRONTEND=noninteractive
    sudo apt-get update

    #PKG_LIST='build-essential devscripts debhelper'
    #if input is a file, convert it to a string like:
    #PKG_LIST=$(cat ./packages.txt)
    PKG_LIST=$1
    for package in $PKG_LIST; do 
        CHECK_PACKAGE=$(sudo dpkg -l \
        | grep --max-count 1 "$package" \
        | awk '{print$ 2}')
            
        if [[ ! -z "$CHECK_PACKAGE" ]]; then 
            echo "$package" 'IS installed'; 
            pkg_installed="yes"
        else 
            echo "$package" 'IS NOT installed, installing';
            sudo apt-get --yes install --no-install-recommends "$package"

            pkg_installed="no"
            package_install "$package"
        fi
    done
    # Delete cached files we don't need anymore
    sudo apt-get clean
}

现在测试一下:

$ source ./package_check.bash
$ PACKAGES=$(cat ./packages.txt) && package_check "$PACKAGES"
Hit:1 http://deb.debian.org/debian bullseye-updates InRelease
Hit:2 http://security.debian.org/debian-security bullseye-security InRelease
Hit:3 http://deb.debian.org/debian bullseye InRelease
Hit:4 http://mirrors.rit.edu/mxlinux/mx-packages/mx/repo bullseye InRelease
Reading package lists... Done
build-essential IS installed
devscripts IS installed
debhelper IS installed
2048 IS NOT installed, installing
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  2048

相关内容