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

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


当前回答

既然你提到了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;

我使用以下方法:

which mySQL 2>&1|tee 1> /dev/null
  if [[ "$?" == 0 ]]; then
                echo -e "\e[42m MySQL already installed. Moving on...\e[0m"
        else
        sudo apt-get install -y mysql-server
                if [[ "$?" == 0 ]]; then
                        echo -e "\e[42mMy SQL installed\e[0m"
                else
                        echo -e "\e[42Installation failed\e[0m"
                fi
        fi

为了更明确一点,这里有一些Bash脚本,用于检查包并在需要时安装它。当然,您可以在发现包丢失时执行其他操作,例如简单地使用错误代码退出。

REQUIRED_PKG="some-package"
PKG_OK=$(dpkg-query -W --showformat='${Status}\n' $REQUIRED_PKG|grep "install ok installed")
echo Checking for $REQUIRED_PKG: $PKG_OK
if [ "" = "$PKG_OK" ]; then
  echo "No $REQUIRED_PKG. Setting up $REQUIRED_PKG."
  sudo apt-get --yes install $REQUIRED_PKG
fi

如果脚本在GUI中运行(例如,它是一个Nautilus脚本),您可能想要用'gksudo'调用替换'sudo'调用。

这一行代码为“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