我正在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

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


当前回答

这一行代码为“nano”包返回1(已安装)或0(未安装)…

$(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed")

即使包不存在或不可用。

下面的例子将安装'nano'包,如果它没有安装…

if [ $(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed") -eq 0 ];
then
  apt-get install nano;
fi

其他回答

我根据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,因为正如评论中提到的,这可能会意外地升级你没有计划的包;对于期望稳定的自动化流程来说,这并不是一个好主意。

如果只使用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

UpAndAdam:

但是,不能简单地依赖这里的返回代码来编写脚本

根据我的经验,你可以依赖dkpg的退出代码。

如果安装了包,dpkg -s的返回码是0,如果没有,返回码是1,所以我找到的最简单的解决方案是:

dpkg -s <pkg-name> 2>/dev/null >/dev/null || sudo apt-get -y install <pkg-name>

这对我来说很好……

所有的答案都很好,但是对于像我这样的初学者来说似乎很复杂。这就是对我有效的解决方案。我的Linux环境是centOS,但不能确定它适用于所有发行版

PACKAGE_NAME=${PACKAGE_NAME:-node}

if ! command -v $PACKAGE_NAME > /dev/null; then
    echo "Installing $PACKAGE_NAME ..."
else
    echo "$PACKAGE_NAME already installed"
fi

Ubuntu添加了它的“个人包存档”(PPA),而PPA包有不同的结果。

A native Debian repository package is not installed: ~$ dpkg-query -l apache-perl ~$ echo $? 1 A PPA package registered on the host and installed: ~$ dpkg-query -l libreoffice ~$ echo $? 0 A PPA package registered on the host, but not installed: ~$ dpkg-query -l 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.

测试APT中是否安装了软件包