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

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


当前回答

受到克里斯回答的启发:

#! /bin/bash

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

pkgs=(libgl1-mesa-dev xorg-dev vulkan-tools libvulkan-dev vulkan-validationlayers-dev spirv-tools)
missing_pkgs=""

for pkg in ${pkgs[@]}; do
    if ! $(installed $pkg) ; then
        missing_pkgs+=" $pkg"
    fi
done

if [ ! -z "$missing_pkgs" ]; then
    cmd="sudo apt install -y $missing_pkgs"
    echo $cmd
fi

其他回答

既然你提到了Ubuntu,而且你想以编程的方式做到这一点(虽然也可以使用dpkg的变体,但实现起来会更复杂),这(这)肯定是可行的:

#!/bin/bash

pkgname=mutt
which $pkgname > /dev/null;isPackage=$?
if [ $isPackage != 0 ];then
        echo "$pkgname not installed"
        sleep 1
        read -r -p "${1:-$pkgname will be installed. Are you sure? [y/N]} " response
        case "$response" in
            [yY][eE][sS]|[yY]) 
                sudo apt-get install $pkgname
                ;;
            *)
                false
                ;;
        esac

else
        echo "$pkgname is installed"
        sleep 1
fi

尽管为了POSIX兼容性,您可能希望使用命令-v,正如在另一个类似问题中提到的那样。

这样的话, 在上面的代码示例中,$pkgname > /dev/null应该被命令-v $pkgname替换。

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中是否安装了软件包

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

这里有一个叫做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;

Use:

apt-cache policy <package_name>

如果没有安装,它将显示:

Installed: none

否则它将显示:

Installed: version

这似乎很有效。

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

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