如何确定在Ubuntu上是否安装了特定软件包?

我几个月前在我的Ubuntu 14.04上安装了一个JDK包,但是我不知道如何检查它的版本。
那么,我该如何找出在Ubuntu上是否安装了某个软件包以及它的版本呢?

虽然这个问题上的一些答案似乎是试图回答这里所问的问题,但大部分问题似乎是在询问如何找出使用tasksel(在服务器安装期间运行)安装了哪些任务。我无法确定那位提问者确切想要什么信息,而且他们确实接受了一个关于检查已安装软件包的答案,尽管不是关于检查单个命名软件包的答案。但我预计大多数通过搜索找到该问题的用户都想了解有关tasksel的信息。 - Eliah Kagan
@EliahKagan由于问题本身以及一些答案涵盖了相关部分,所以我不认为这种区别有多大意义(否则,我不会期望这样 - 我是通过在Google上搜索"ubuntu check package installed"得到它的,对我来说这是顶部的结果)。 - muru
1@muru 你对于如何在没有超级用户权限的情况下检查软件包是否已安装?有什么看法?似乎还有其他几个相关问题被关闭为该问题的重复,(也许这些问题中的一些答案可以合并到选择的重复目标中?) - Eliah Kagan
@EliahKagan 是的,那个不错。 - muru
4个回答

太长不读:对于没有| grep的简单命令和紧凑输出,你可以使用:
  • apt list package,通常是你想要的(与apt-cache policy package比较),或者
  • dpkg-query -W package作为一个更简洁版本的dpkg -l package

apt命令(针对apt list package)在Ubuntu 14.04及更高版本中可用。

apt list会告诉你是否安装了软件包。

apt list package显示了已安装或将要安装的软件包的版本,以及提供该软件包的仓库组件的名称和版本。当软件包已安装时,[installed]会在行尾显著地出现。

ek@Io:~$ apt list firefox
Listing... Done
firefox/xenial-updates,xenial-security,now 51.0.1+build2-0ubuntu0.16.04.1 amd64 [installed]
N: There is 1 additional version. Please use the '-a' switch to see it

除了末尾的[已安装]之外,列表中的now表示该软件包当前已安装。这是对于一个未安装的软件包,apt list的输出如下所示:
ek@Io:~$ apt list dolphin
Listing... Done
dolphin/xenial 4:15.12.3-0ubuntu1 amd64

有时候你会看到[已安装,自动安装],这意味着该软件包是作为其他软件包的依赖项而安装的。由于它是自动安装而不是手动安装的,所以在删除所有依赖于它的软件包之后可以将其删除(这就是apt autoremove命令的作用)。
ek@Io:~$ apt list zeitgeist-core
Listing... Done
zeitgeist-core/xenial,now 0.9.16-0ubuntu4 amd64 [installed,automatic]

您可以使用apt list --installed命令来显示已安装的软件包。

即使软件包未安装,查看列表的一个优点是您知道有一个与您指定名称相同的软件包。否则,如果您意外拼写错误,您可能会认为您想要的软件包未安装。

ek@Io:~$ apt list firefoz
Listing... Done

但是如果你真的希望在没有安装包的情况下什么都不显示,可以使用apt list --installed package
ek@Io:~$ apt list --installed firefox dolphin
Listing... Done
firefox/xenial-updates,xenial-security,now 51.0.1+build2-0ubuntu0.16.04.1 amd64 [installed]
N: There is 1 additional version. Please use the '-a' switch to see it

通配符能够帮助您列出那些名称不知道或不想键入的软件包。

正如您刚刚看到的,您可以将多个软件包名称传递给apt list命令。另一种方法是传递一个通配符, 其中*代表零个或多个字符,?代表一个字符。需要记住以下几点:

  • 你的shell也会将通配符扩展为文件名, 但这不是你想要发生的事情,所以当你将它们传递给apt list时,你应该始终将它们用引号括起来(使用''"",或者使用\)。
  • 虽然通配符和正则表达式都支持字符类(例如,[csz]sh匹配cshsshzsh),但它们并不相同,并且在通配符中,*?表示不同的含义。这很重要,因为一些用于获取有关软件包信息的其他命令,例如apt-cache policy package,使用的是正则表达式而不是通配符。在依赖于这两个功能之前,你应该检查一个命令是否使用通配符还是正则表达式。
  • 当你实际添加和删除软件包时,你绝不能混淆通配符和正则表达式。 apt list 'wine*'列出所有名称以wine开头的软件包,但apt remove 'wine*'会删除所有名称中包含win(甚至没有e)的软件包!
假设,例如,我知道我感兴趣的包裹名称中有“soap”并以“cil”结尾,但这是我唯一记得的内容。
ek@Io:~$ apt list '*soap*cil'
Listing... Done
libmono-system-runtime-serialization-formatters-soap4.0-cil/xenial,xenial,now 4.2.1.102+dfsg2-7ubuntu4 all [installed,automatic]

Globbing在你知道感兴趣的软件包的完整名称,但不想输入时非常方便。或者当你对匹配通配符的多个软件包感兴趣时也很有用。
ek@Io:~$ apt list 'firefox-locale-*'
Listing... Done
firefox-locale-af/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-an/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ar/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-as/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ast/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-az/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-be/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-bg/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-bn/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-br/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-bs/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ca/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-cak/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-cs/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-csb/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-cy/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-da/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-de/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-el/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-en/xenial-updates,xenial-security,now 51.0.1+build2-0ubuntu0.16.04.1 amd64 [installed]
firefox-locale-eo/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-es/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-et/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-eu/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-fa/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-fi/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-fr/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-fy/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ga/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-gd/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-gl/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-gn/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-gu/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-he/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-hi/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-hr/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-hsb/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-hu/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-hy/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-id/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-is/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-it/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ja/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ka/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-kab/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-kk/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-km/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-kn/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ko/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ku/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-lg/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-lt/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-lv/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-mai/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-mk/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ml/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-mn/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-mr/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ms/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-nb/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-nl/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-nn/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-nso/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-oc/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-or/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-pa/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-pl/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-pt/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ro/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ru/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-si/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-sk/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-sl/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-sq/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-sr/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-sv/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-sw/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-ta/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-te/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-th/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-tr/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-uk/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-uz/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-vi/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-xh/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-zh-hans/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-zh-hant/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64
firefox-locale-zu/xenial-updates,xenial-security 51.0.1+build2-0ubuntu0.16.04.1 amd64

这是很多的软件包。(虽然没有像我运行apt list '*'那样多,它列出了所有可用的软件包!) 幸运的是,通配符也适用于--installed
ek@Io:~$ apt list --installed 'firefox-locale-*'
Listing... Done
firefox-locale-en/xenial-updates,xenial-security,now 51.0.1+build2-0ubuntu0.16.04.1 amd64 [installed]
N: There is 1 additional version. Please use the '-a' switch to see it

apt list vs. dpkg-query -W

另一个你可以使用的命令是dpkg-query -W package。这与dpkg -l类似,但其输出更简洁和易读,因为只打印了软件包名称和已安装版本(如果有)。

dpkg-query -W列出了所有与你提供的名称或通配符模式匹配的dpkg所知道的软件包。这包括已安装的软件包以及未安装但被其他软件包引用的软件包。你可以通过右侧打印的已安装版本号/字符串来确定哪些软件包实际上已安装。例如,在我的16.04系统上:

ek@Io:~$ dpkg-query -W wine-\*
wine-amd64
wine-gecko
wine-gecko2.21:amd64    2.21-0ubuntu1
wine-gecko2.21:i386     2.21-0ubuntu1
wine-i386
wine-mono
wine-mono0.0.8  0.0.8-0ubuntu1

因此,在列出的软件包中,wine-gecko2.21:amd64wine-gecko2.21:i386(即wine-gecko2.21适用于amd64i386架构)以及wine-mono0.0.8是我当前已安装的软件包。 dpkg-query -Wapt list都会始终知道已安装的软件包,无论它们是否由任何当前配置的软件源提供,以及它们是否被其他软件包引用。然而:
  • apt list也知道来自任何当前配置的软件源的可用软件包,但不知道其他软件包引用的不可用软件包。
  • dpkg-query -W(就像dpkg -l一样)不直接反映实际可用的软件包,但确实知道由任何已安装的软件包引用的软件包。
在同一台机器上:
ek@Io:~$ apt list wine-\*
Listing... Done
wine-development/xenial,xenial 1.9.6-1 all
wine-gecko2.21/xenial,now 2.21-0ubuntu1 amd64 [installed,automatic]
wine-mono0.0.8/xenial,xenial,now 0.0.8-0ubuntu1 all [installed,automatic]

dpkg -l一样,当您使用没有安装的软件包名称运行dpkg-query -W时(例如,我没有安装chocolate-doom),输出结果与使用根本不存在的软件包名称运行它时相同(例如,由于拼写错误,如firefoz):
ek@Io:~$ dpkg-query -W chocolate-doom firefoz
dpkg-query: no packages found matching chocolate-doom
dpkg-query: no packages found matching firefoz

相比之下,apt list 明确显示只有 chocolate-doom 存在(但尚未安装)。
ek@Io:~$ apt list chocolate-doom firefoz
Listing... Done
chocolate-doom/xenial 2.2.1-2.1 amd64

在终端中运行dpkg -l | grep <name or pattern>。例如,
dpkg -l | grep firefox
ii  firefox       51.0.1+build2-0ubuntu0.14.04.2                      amd64 

这个ii的意思是已安装。显然,如果没有输出,那么该软件包就没有安装。

4或者只需运行dpkg -l firefox - lamino

如果你知道软件包的名称,可以使用 apt-cache policy 命令来查询。
$ apt-cache policy firefox | grep 'Installed:'                                                                           
  Installed: 51.0.1+build2-0ubuntu0.16.04.1
$ apt-cache policy golang | grep 'Installed:'                                                                            
  Installed: (none)

如果你不知道,可以使用dpkg --get-selections | grep 'jdk'命令。
$ dpkg --get-selections | grep 'jdk'
jdk1.8.0-111                    deinstall
openjdk-7-jre-headless:amd64            deinstall
openjdk-8-jdk:amd64             install
openjdk-8-jdk-headless:amd64            install
openjdk-8-jre:amd64             install
openjdk-8-jre-headless:amd64            install
openjdk-9-jre-headless:amd64            deinstall

使用dpkg命令,它是Debian的软件包管理器。
>dpkg -s /package name/  

使用文件/var/lib/dpkg/available来查找所有可用的软件包名称。
或者您可以使用以下命令(它会列出/var/lib/dpkg/status中的所有软件包):
>dpkg-query -l  

你还可以尝试使用通配符来匹配软件包名称。
>dpkg-query -l 'libc6*'

1这是不正确的。dpkg-query -l命令会列出你安装过并且已经移除的软件包。 - josch
dpkg -s 也会显示已卸载的软件包。 - undefined