测试软件包是否已安装在 APT 中

测试软件包是否已安装在 APT 中

我想要一个 shell 脚本方法来测试/报告某个包是否已安装。我不需要详细信息,只需要布尔值返回来设置逻辑流程。我查看了查找包是否已安装,但dpkg返回复杂的输出,并且其格式会根据包是在 Debian 存储库中还是在 Ubuntu PPA 中而变化。

我发现这个方法apt-cache效果很好,所以我想出了这个方法:

is_installed=0
test_installed=( `apt-cache policy package-name | grep "Installed:" ` )
[ ! "${test_installed[1]}" == "(none)" ] && is_installed=1

有人知道更简单或更直接的方法吗?

答案1

dpkg-query正如您所链接的帖子中所说,这似乎是最适合这项工作的工具,除了使用例如可用的 Python 库在这样的脚本上下文中直接绑定到 APT 系统。

dpkg-query

dpkg-query -Wf'${db:Status-abbrev}' package-name 2>/dev/null | grep -q '^i'

0如果包已安装,将返回 true (shell 脚本中的退出状态),1否则将返回 false (退出状态)。

  • -W表示“显示”(dpkg-query必须有一个请求的操作)。
  • -f改变输出的格式。
  • db:Status-abbrev是包裹状态的简称。
  • 2>/dev/null如果给出的包名无效,则保持沉默dpkg-query。如何处理这个问题可能是一个具体问题具体分析的问题。
  • grep -q如果匹配则返回 true,否则返回 false。

如果经常使用,可以将其做成一个简单的函数:

#!/bin/sh
debInst() {
    dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'
}

if debInst "$1"; then
    printf 'Why yes, the package %s _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package %s is not currently installed.\n' "$1"
fi

或者只是

#!/bin/sh
if dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'; then
    printf 'Why yes, the package "%s" _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package "%s" is not currently installed.\n' "$1"
fi

答案2

我喜欢 Daniel Andersson 的回答,但它对我不起作用。我在 Ubuntu 12.04 上。

来自dpkg 手册页db:Status-abbrev仅适用于 dpkg 1.16.2+:

          db:Status-Abbrev
                 It  contains the abbreviated package status, such as “ii”
                 (since dpkg 1.16.2).

我的解决方案是使用旧行为,仅使用Status格式化程序:

dpkg-query -Wf'${Status}' {my_pkg_name}

输出

install ok installed 

我猜想这是其他表述中“ii”的灵感来源。

因此,为了完全适应 Daniel Andersson 的答案,以适用于旧版本的 dpkg,以及旧版本的 Ubuntu 发行版:

dpkg-query -Wf'${Status}' {your_pkg_name} 2>/dev/null | grep -q "install ok installed"

返回:

  • 0-软件包已安装,或
  • 1-包未安装。

答案3

我在三个软件包上测试了 Daniel 的建议,结果如下:

  1. 未安装本机 Debian 存储库包:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. PPA 包在主机上注册并安装:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. PPA 包在主机上注册但未安装:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' domy-ce
    ~$ echo $?
    0
    ~$ sudo apt-get remove domy-ce
    [sudo] password for user: 
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    Package domy-ce is not installed, so not removed
    0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
    

虽然我喜欢这种方法,但我似乎不能相信 PPA 软件包的返回代码。除此之外,我想我会坚持解析命令的返回值apt-cache policy

答案4

#!/bin/bash

# Check for dependencies 
check_deps () {
DEPS=$(echo {dialog,sqlite3,openssh-client})
for i in $DEPS ; do
    dpkg-query -W -f='${Package}\n' | grep ^$i$ > /dev/null
    if [ $? != 0 ] ; then
        echo "Installing deps ..."
        aptitude install $i -y > /dev/null
    fi
done  
}

# execute the check_deps function
check_deps

相关内容