Check if an apt-get package is installed and then install it if it's not on Linux?
我正在开发一个Ubuntu系统,目前我正在做的是:
1 2 3 4 5 6 7 | 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 |
这是大多数人都会做的吗?还是有更优雅的解决方案?
要检查是否安装了
1 | dpkg -s <packagename> |
你也可以使用输出更整齐的
1 | dpkg-query -l <packagename> |
要找到拥有
1 | dpkg -S `which <command>` |
有关进一步的详细信息,请参阅文章了解Linux和DPKG技术手册中是否安装了软件包。
更明确一点,这里有一些bash脚本,用于检查包并在需要时安装它。当然,您可以在发现包丢失时执行其他操作,例如只使用错误代码退出。
1 2 3 4 5 6 7 | PKG_OK=$(dpkg-query -W --showformat='${Status} ' the.package.name|grep"install ok installed") echo Checking for somelib: $PKG_OK if ["" =="$PKG_OK" ]; then echo"No somelib. Setting up somelib." sudo apt-get --force-yes --yes install the.package.name fi |
如果脚本在一个GUI中运行(例如,它是一个Nautilus脚本),那么您可能需要将"sudo"调用替换为"gksudo"调用。
此一行程序返回"nano"包的1(已安装)或0(未安装)。
1 | $(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c"ok installed") |
即使包不存在/不可用。
下面的示例安装"nano"软件包(如果未安装)。
1 2 3 4 | if [ $(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c"ok installed") -eq 0 ]; then apt-get install nano; fi |
我提供这个更新是因为Ubuntu在回答这个问题时添加了它的"个人软件包存档"(ppa),而ppa软件包有不同的结果。
未安装本机Debian存储库包:
1 2 3 | ~$ dpkg-query -l apache-perl ~$ echo $? 1 |
在主机上注册并安装的ppa包:
1 2 3 | ~$ dpkg-query -l libreoffice ~$ echo $? 0 |
在主机上注册但未安装的ppa包:
1 2 3 4 5 6 7 8 9 10 | ~$ 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. |
也发布在:https://superuser.com/questions/427318/test-if-a-package-is-installed-in-apt/427898
我喜欢
1 2 3 4 | pkgs='qemu-user pandoc' if ! dpkg -s $pkgs >/dev/null 2>&1; then sudo apt-get install $pkgs fi |
参见:
- https://askubuntu.com/questions/423355/how-do-i-check-if-a-package-is-installed-on-my-server
在Ubuntu 18.10上测试。
这似乎很管用。
1 | $ sudo dpkg-query -l | grep <some_package_name> | wc -l |
- 如果没有安装,则返回
0 ,如果安装,则返回一些数字> 0 。
乌班达姆写道:
However you can't simply rely on return codes here for scripting
根据我的经验,你可以依靠DKPG的出口代码。
dpkg-s的返回码是0,如果安装了包,返回码是1,所以我找到的最简单的解决方案是:
1 | dpkg -s <pkg-name> 2>/dev/null >/dev/null || sudo apt-get -y install <pkg-name> |
对我来说很好…
我发现,如果安装了一个软件包,然后将其删除,但安装软件包仍保留在系统上,那么上面的所有解决方案都会产生误报。
复制:安装
现在测试以上答案。
以下命令似乎可以解决此问题:
' curl | head -n1 | awk '{print $3;}' | grep -q '^installed$'
这将导致是否已安装
我已经根据努尔蒂的回答决定了一个问题:
1 2 3 | 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 |
基本上,来自
说明/示例:
1 2 3 4 5 6 | $ 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从错误消息中提取包名称,从而生成
我并不是盲目地发布
1 2 3 | $name="rsync" [ `which $name` ] $$ echo"$name : installed" || sudo apt-get install -y $name |
这就行了。
1 | sudo apt-get install command |
用途:
1 | apt-cache policy <package_name> |
如果未安装,将显示:
1 | Installed: none |
否则将显示:
1 | Installed: version |
1 | apt list [packagename] |
似乎是除dpkg和旧的apt-*工具之外最简单的方法。
对于Ubuntu来说,apt提供了一种相当不错的方法。下面是Google Chrome的一个例子:
我将错误输出重定向为空,因为APT警告不要使用它的"不稳定的CLI"。我怀疑列表包是稳定的,所以我认为可以扔掉这个警告。QQ让APT超级安静。
在本地运行测试时,我有一个类似的要求,而不是在Docker中。基本上,我只想安装任何尚未安装的.deb文件。
1 2 3 4 5 6 7 8 9 10 11 12 | # If there are .deb files in the folder, then install them if [ `ls -1 *.deb 2> /dev/null | wc -l` -gt 0 ]; then for file in *.deb; do # Only install if not already installed (non-zero exit code) dpkg -I ${file} | grep Package: | sed -r 's/ Package:\s+(.*)/\1/g' | xargs dpkg -s if [ $? != 0 ]; then dpkg -i ${file} fi; done; else err"No .deb files found in '$PWD'" fi |
我想我能看到的唯一问题是它没有检查包的版本号,所以如果.deb文件是一个较新的版本,那么它不会覆盖当前安装的包。
这个特性已经存在于Ubuntu和Debian中,在
我使用以下方法:
1 2 3 4 5 6 7 8 9 10 11 | 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 |
这个命令最令人难忘:
1 | dpkg --get-selections <package-name> |
如果已安装,则打印:
install
否则它会打印
No packages found matching
.
这是在Ubuntu 12.04.1(精确穿山甲)上测试的。
很多事情已经被告知,但对我来说最简单的方法是:
1 | dpkg -l | grep packagename |
在巴什:
1 2 | PKG="emacs" dpkg-query -l $PKG > /dev/null || sudo apt install $PKG |
注意,在pkg中可以有一个包含多个包的字符串。
1 2 3 4 | which <command> if [ $? == 1 ]; then <pkg-manager> -y install <command> fi |