我正在Ubuntu系统上工作,目前我正在做的是:

if ! which command > /dev/null; then
   echo -e "Command not found! Install? (y/n) \c"
   read
   if "$REPLY" = "y"; then
      sudo apt-get install command
   fi
fi

大多数人都会这么做吗?还是有更优雅的解决方案?


当前回答

这似乎很有效。

$ sudo dpkg-query -l | grep <some_package_name> | wc -l

如果没有安装,则返回0;如果安装,则返回某个数字> 0。

其他回答

如果只使用awk安装了else 1,则显式打印0:

dpkg-query -W -f '${Status}\n' 'PKG' 2>&1|awk '/ok installed/{print 0;exit}{print 1}'

或者如果你喜欢另一种方式,1表示安装,0表示:

dpkg-query -W -f '${Status}\n' 'PKG' 2>&1|awk '/ok installed/{print 1;exit}{print 0}'

**用您的包名替换PKG

便利功能:

installed() {
    return $(dpkg-query -W -f '${Status}\n' "${1}" 2>&1|awk '/ok installed/{print 0;exit}{print 1}')
}


# usage:
installed gcc && echo Yes || echo No

#or

if installed gcc; then
    echo yes
else
    echo no
fi

如果您的包具有命令行接口,则可以在安装之前通过调用它的命令行工具来计算输出,从而检查包是否存在。

这里有一个叫做helm的包的例子。

#!/bin/bash

# Call the command for the package silently
helm > /dev/null

# Get the exit code of the last command
command_exit_code="$(echo $?)"

# Run installation if exit code is not equal to 0
if [ "$command_exit_code" -ne "0" ]; then
    # Package does not exist: Do the package installation
else
   echo "Skipping 'helm' installation: Package already exists"
fi;

这个就行了。Apt-get install是幂等的。

sudo apt-get install --no-upgrade command

我根据Nultyi的回答选择了一个:

MISSING=$(dpkg --get-selections $PACKAGES 2>&1 | grep -v 'install$' | awk '{ print $6 }')
# Optional check here to skip bothering with apt-get if $MISSING is empty
sudo apt-get install $MISSING

基本上,来自dpkg——get-selections的错误消息比其他大多数错误消息更容易解析,因为它不包括“deinstall”这样的状态。它还可以同时检查多个包,这是仅使用错误代码无法做到的。

解释/例子:

$ dpkg --get-selections  python3-venv python3-dev screen build-essential jq
dpkg: no packages found matching python3-venv
dpkg: no packages found matching python3-dev
screen                                          install
build-essential                                 install
dpkg: no packages found matching jq

因此grep从列表中删除已安装的包,awk从错误消息中提取包名,导致MISSING='python3-venv python3-dev jq',它可以简单地插入到安装命令中。

我不是盲目地发布apt-get install $PACKAGES,因为正如评论中提到的,这可能会意外地升级你没有计划的包;对于期望稳定的自动化流程来说,这并不是一个好主意。

建议使用以下内容的答案:

dpkg-query --showformat '${db:Status-Status}\n' --show $package | grep -q '^installed$'
dpkg-query --showformat '${Status}\n' --show $package | grep -q '^install ok installed$'

是正确的。

但是如果你已经安装了dpkg-dev包,你不只是想检查一个包是否安装了,你还需要:

想知道一个包是否安装在某个版本 希望在特定的体系结构中拥有一个包 查看是否提供了虚拟包

然后你可以滥用dpkg-checkbuilddeps工具来完成这项工作:

dpkg-checkbuilddeps -d apt /dev/null

这将检查是否安装了apt。

下面将检查apt是否至少在2.3.15版本中安装,grep是否作为amd64安装,并且某些已安装的包中提供了虚拟包x-window-manager:

dpkg-checkbuilddeps -d 'apt (>= 2.3.15), grep:amd64, x-window-manager' /dev/null

dpkg-checkbuilddeps的退出状态将告诉脚本依赖项是否满足。由于此方法支持传递多个包,因此即使希望检查是否安装了多个包,也只需运行一次dpkg-checkbuilddeps。