在 Gentoo 中,有一个文件/var/lib/portage/world
包含我明确安装的软件包。我的意思是,我选择的包,不包括默认安装的任何东西,或者由依赖项拉入的包。
Ubuntu 中是否有类似的文件或命令可以查找该信息?
答案1
只是代码
aptitude search '~i !~M' -F '%p' --disable-columns | sort -u > currentlyinstalled.txt
wget -qO - http://mirror.pnl.gov/releases/precise/ubuntu-12.04.3-desktop-amd64.manifest \
| cut -f1 | sort -u > defaultinstalled.txt
comm -23 currentlyinstalled.txt defaultinstalled.txt
解释
思考这个问题的一种方法是将其分为三个部分:
- 如何获取未作为依赖项安装的软件包列表?
- 如何获取默认安装的软件包列表?
- 我怎样才能得到这两个列表之间的差异?
如何获取未作为依赖项安装的软件包列表?
以下命令似乎适用于我的系统:
$ aptitude search '~i !~M' -F '%p' --disable-columns | sort -u > currentlyinstalled.txt
类似的方法可以在吉尔斯作为对该问题的评论发布的链接中找到。一些消息来源声称,只有当您使用 aptitude 安装软件包时,这才有效;然而,我几乎从不使用 aptitude 安装软件包,发现这仍然有效。这--disable-columns
可以防止 aptitude 用空白填充包名称行,从而阻碍下面的比较。对| sort -u
文件进行排序并删除重复项。这使得最后一步变得更加容易。
如何获取默认安装的软件包列表?
笔记:本节从一条我认为具有说明性的“错误路径”开始。第二段代码是有效的。
这有点棘手。我最初认为一个很好的近似是元包 ubuntu-minimal、ubuntu-standard、ubuntu-desktop 以及各种 linux 内核相关包的依赖项的所有包。谷歌搜索的一些结果似乎使用了这种方法。为了获取这些依赖项的列表,我首先尝试了以下方法(但不起作用):
$ apt-cache depends ubuntu-desktop ubuntu-minimal ubuntu-standard linux-* | awk '/Depends:/ {print $2}' | sort -u
这似乎遗漏了一些我知道默认情况下必须提供的软件包。我仍然相信,如果构建正确的元包列表,这种方法应该有效。
然而,Ubuntu 镜像似乎包含一个“清单”文件,其中包含默认安装中的所有软件包。 Ubuntu 12.04.3 的清单在这里:
http://mirror.pnl.gov/releases/precise/ubuntu-12.04.3-desktop-amd64.manifest
如果您搜索此页面(或离您较近的镜子页面):
http://mirror.pnl.gov/releases/precise/
您应该能够找到与您正在使用的版本和架构相对应的“.manifest”文件。为了仅提取包名称,我这样做了:
wget -qO - http://mirror.pnl.gov/releases/precise/ubuntu-12.04.3-desktop-amd64.manifest | cut -f1 | sort -u > defaultinstalled.txt
该列表可能已经排序并且是唯一的,但我想确保它已正确排序以使下一步更容易。然后我将输出放入defaultinstalled.txt
.
我怎样才能得到这两个列表之间的差异?
这是最简单的部分,因为大多数类 Unix 系统都有许多工具可以完成此任务。该comm
工具是执行此操作的多种方法之一:
comm -23 currentlyinstalled.txt defaultinstalled.txt
这应该打印第一个文件特有的行列表。因此,它应该打印不在默认安装中的已安装软件包的列表。
答案2
您可以使用这两个单行代码中的任何一个。两者在我的机器上产生完全相同的输出,并且比迄今为止(2014 年 7 月)在此问题中提出的所有解决方案更精确。它们是两个答案的组合(1)和(2)。请注意,我最初发布了这个答案这里。
使用apt-mark
:
comm -23 <(apt-mark showmanual | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)
使用aptitude
:
comm -23 <(aptitude search '~i !~M' -F '%p' | sed "s/ *$//" | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)
尽管我怀疑这些,但仍然很少有包裹被漏掉是由用户实际安装,或者在安装后立即通过语言本地化设置安装,或者通过 Totem 编解码器安装程序安装。此外,即使我只安装了非特定版本的元包,linux-header 版本似乎也在累积。例子:
libreoffice-help-en-gb
openoffice.org-hyphenation
gstreamer0.10-fluendo-mp3
linux-headers-3.13.0-29
它是如何工作的
- 获取手动安装的软件包列表。对于 aptitude,附加的内容
sed
会去除行尾剩余的空格。 - 全新安装后立即获取已安装的软件包列表。
- 比较文件,仅输出文件 1 中文件 2 中不存在的行。
其他可能性也不起作用:
- 使用
ubuntu-14.04-desktop-amd64.manifest
文件(这里对于 Ubuntu 14.04) 而不是/var/log/installer/initial-status.gz
.更多软件包显示为手动安装,即使它们不是手动安装的。 - 使用
apt-mark showauto
而不是/var/log/installer/initial-status.gz
.apt-mark
例如,不包含 xserver-xorg 包,而另一个文件则包含。
两者都列出了比上述解决方案更多的包。
答案3
根据man apt-mark
:
apt-mark showauto
apt-mark showmanual
答案4
当我搜索这个查询时,我发现了这个漂亮的 oneliner
第一个班轮是
comm -13 \
<(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort) \
<(comm -23 \
<(dpkg-query -W -f='${Package}\n' | sed 1d | sort) \
<(apt-mark showauto | sort) \
)`
此 oneliner 使用以下日志过滤系统安装的软件包/var/log/installer/initial-status.gz
当我找到它时,我会发布原始线程的链接,因为这个 oneliner 不是我的,而且我似乎不记得我在哪里看到它。