对于某些库,很难确定软件包是否已经安装。有没有一种简单的方法/命令来检查这个?
apt-cache policy <package name>
dpkg -l | grep mysql
dpkg -l "*mysql*"
也可以工作,并且不会隐藏输出中的解释性行。 - Philipp Wendlerdpkg -l "*mysql*"
(或 dpkg -l '*mysql*'
)还可以对输出进行特殊格式化,以适应终端窗口中每个软件包的一行显示(grep不能做到)。而且这种形式允许您选择通配符的格式(前缀或后缀),以及是否使用通配符(与grep相比)。但是grep提供了漂亮的着色效果.. )) - vstepaniukdpkg -l
不会要求 dpkg 列出所有已安装的软件包。dpkg -l
的输出还会包括你安装但后来删除的软件包。正确的方法是通过检查 dpkg -l
输出的第一列是否等于 ii
或者运行:dpkg-query --showformat '${Status}\n' --show $pkg
,它将对实际安装的软件包显示 install ok installed
。 - joschaptitude show <package>
dpkg -s <软件包名称>
提供了与软件包相关的许多详细信息。例如"userme:~$ dpkg-query -s sl
Package: sl
Status: unknown ok not-installed
Priority: optional
Section: games
dpkg -s
来实现。反之,dpkg-query -l
同样可以像 dpkg -l
或 dpkg --list
一样正常工作。 - belacquadpkg-query -s <package> 2>/dev/null | grep -q ^"Status: install ok installed"$
命令,如果<package>
未安装,则返回退出码1,如果<package>
已安装,则返回退出码0。dpkg -s
返回0
,并不一定意味着软件包已经完全/正确地安装。如果软件包处于half-configured
或者config-files
状态,dpkg -s
同样会返回0
(我猜在half-installed
状态下也是如此,但我没有检查过)。请参考dpkg的手册页面了解更多关于"不完整"状态的信息。 - Ignitordpkg-query --showformat='${db:Status-Status}'
这会生成一个小的输出字符串,不太可能改变,并且很容易进行确定性比较,而无需使用grep
:
pkg=hello
status="$(dpkg-query -W --showformat='${db:Status-Status}' "$pkg" 2>&1)"
if [ ! $? = 0 ] || [ ! "$status" = installed ]; then
sudo apt install $pkg
fi
$? = 0
检查,因为如果您以前从未安装过软件包,并且在删除某些软件包(例如hello
)之后,dpkg-query
将以状态1退出并输出到stderr。dpkg-query: no packages found matching hello
而不是输出not-installed
。当出现错误消息时,2>&1
也会捕获该消息,防止其进入终端。
对于多个软件包:
pkgs='hello certbot'
install=false
for pkg in $pkgs; do
status="$(dpkg-query -W --showformat='${db:Status-Status}' "$pkg" 2>&1)"
if [ ! $? = 0 ] || [ ! "$status" = installed ]; then
install=true
break
fi
done
if "$install"; then
sudo apt install $pkgs
fi
man dpkg-query
中有详细记录: n = Not-installed
c = Config-files
H = Half-installed
U = Unpacked
F = Half-configured
W = Triggers-awaiting
t = Triggers-pending
i = Installed
单个字母版本可以通过db:Status-Abbrev
获得,但它们会同时包含动作和错误状态,所以你会得到3个字符,需要进行截取。
因此,我认为依赖于未大写的状态(Config-files
vs config-files
)不会改变是可靠的。
dpkg -s
退出状态
不幸的是,这并不是大多数用户想要的功能:
pkgs='qemu-user pandoc'
if ! dpkg -s $pkgs >/dev/null 2>&1; then
sudo apt-get install $pkgs
fi
certbot
,执行以下操作:sudo apt install certbot
sudo apt remove certbot
将certbot
保留在“config-files”状态,这意味着配置文件仍然留在机器上。在这种状态下,dpkg -s
仍然返回0
,因为软件包元数据仍然保留,以便更好地处理这些配置文件。
要实际使dpkg -s
返回所需的1,需要使用--purge
:
sudo apt remove --purge certbot
这实际上将其移动到not-installed
/dpkg-query: no packages found matching
。
请注意,只有某些软件包会留下配置文件。像hello
这样的简单软件包会直接从installed
转到not-installed
,而无需使用--purge
。
在Ubuntu 20.10上进行了测试。
Python apt
软件包
在Ubuntu 18.04中有一个预安装的Python 3软件包,名为apt
,它提供了一个Python apt接口!
可以在以下链接中找到一个检查软件包是否已安装并在未安装时安装它的脚本:https://stackoverflow.com/questions/17537390/how-to-install-a-package-using-the-python-apt-api/17538002#17538002
以下是供参考的副本:
#!/usr/bin/env python
# aptinstall.py
import apt
import sys
pkg_name = "libjs-yui-doc"
cache = apt.cache.Cache()
cache.update()
cache.open()
pkg = cache[pkg_name]
if pkg.is_installed:
print "{pkg_name} already installed".format(pkg_name=pkg_name)
else:
pkg.mark_install()
try:
cache.commit()
except Exception, arg:
print >> sys.stderr, "Sorry, package installation failed [{err}]".format(err=str(arg))
检查可执行文件是否在PATH
中
另请参阅
dpkg -s
命令也会返回零。你可以自己尝试,在你的系统上运行 dpkg -l
命令并将一个在 dpkg -l
输出的第一列中带有“rc”的软件包传递给 dpkg -s
。即使该软件包未安装,dpkg -s
也会成功退出。 - joschdpkg-query -W --showformat='${Status}\n' ...
的解决方案不完美呢? - joschinstall ok installed
这个字符串有点长,不太容易用grep查找。虽然我还没有进行详细的研究。 - Ciro Santilli OurBigBook.comdpkg-query -W --showformat='${db:Status-Status}'
看起来还不错,只输出 installed
。 - Ciro Santilli OurBigBook.com${Status}
给出了 /var/lib/dpkg/status
中 Status
字段的纯值。如果您使用的是 dpkg 1.17.11 或更高版本,那么 ${db:Status-Status}
将给您提供所需的内容,而不包括 "eflag" 或 "want"。关于稳定性:自 1995 年以来,这一点没有改变。对您来说,这是否足够稳定?证明:https://git.hadrons.org/cgit/debian/dpkg/dpkg.git/tree/lib/parsehelp.c?id=1b80fb16c22db72457d7a456ffbf1f70a8dfc0a5#n77 至于文档:只需执行 man dpkg
并查看 INFORMATION ABOUT PACKAGES
部分,所有字段值(如 installed
)都在那里有记录。 - joschapt list <package>
man apt
。apt show
命令获取更多详细信息。 - wjandreadpkg -l
打印的状态,例如:$ dpkg -l firefox-esr vim winff
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-====================================-=======================-=======================-=============================================================================
hi firefox-esr 52.9.0esr+build2-0ubunt amd64 Safe and easy web browser from Mozilla
ii vim 2:8.1.1198-0york0~14.04 amd64 Vi IMproved - enhanced vi editor
rc winff 1.5.3-3 all graphical video and audio batch converter using ffmpeg or avconv
vim
和firefox-esr
,因此您可以键入:$ dpkg -l firefox-esr | grep -q ^.i && echo This package is installed. || echo This package is NOT installed.
This package is installed.
$ dpkg -l vim | grep -q ^.i && echo This package is installed. || echo This package is NOT installed.
This package is installed.
$ dpkg -l winff | grep -q ^.i && echo This package is installed. || echo This package is NOT installed.
This package is NOT installed.
在shell脚本中使用特定值作为变量的示例(例如test.sh
)
#!/bin/sh
PACKAGE="${1}"
INSTALLED=$(dpkg -l | grep ${PACKAGE} >/dev/null && echo "yes" || echo "no")
echo "${PACKAGE} is installed ... ${INSTALLED}"
test.sh openssh-server
或者在你的脚本中随意处理
dpkg -l
命令会列出你曾经安装但后来卸载的软件包。而且,像你所做的那样,在dpkg -l
输出中使用grep命令也会匹配到软件包描述中的所有文本。正确的方法是使用dpkg-query -W --showformat='${db:Status-Status}' $package
命令。 - josch
dpkg -s
命令可以提供更多信息,详见:https://askubuntu.com/a/1108801/52975 - Ciro Santilli OurBigBook.comapt
命令:apt policy <软件包名称>
或apt show <软件包名称>
以获取更多信息。 - Pablo Bianchi