您如何跟踪Ubuntu(Linux)上安装了哪些软件包?


38

(此问题与10458非常相似。有人建议Fedora和Ubuntu / Debian的区别足以保证提供不同的答案。)

当我使用任何Ubuntu安装程序时,我会在基准安装之上逐步安装许多软件包。如果我重新安装,或者需要安装新计算机,通常我想重新安装那些特定的程序包,并且我想尽快地重新安装,以尽量减少麻烦。至于我见过的所有的包管理器(apt-getaptitudesynaptic)可以告诉我安装了哪些软件包,它们都具有日志(尽管不同的人对于每一个工具,这是一个麻烦)。但没有人能告诉我这包我已经已安装,而不是依赖项或系统更新。即使是日志也很棘手,因为我不确定我应该从中提取什么,或者如何集成它们(对于各种合适的家庭工具而言)。这意味着每次我重新安装甚至只是备份时,都不确定如何重新创建该列表。

我不一定期望有任何工具可以为我做到这一点,但是如果没有,我正在寻找解决方法。即使是grep的模式,良好的经验法则或明确记录的确切内容,也会很有用。这里可能没有“最佳答案”,但是好的答案会很有帮助。


以下大多数答案提供了我所寻找的大致信息,并且在某种程度上很有用。选择的是最接近自动将我的工具重新安装到新系统上的合理方式,即使有所有注意事项。


对于所有Linux发行版,您不太可能获得一个容易共享的答案。软件包管理是区分不同Linux发行版的重要组成部分。
Telemachus

Telemachus-是的。将其分为两个问题可能很有意义。但是,这似乎是一个相当专业的问题,我同时使用了这两个系统,所以我不想提前缩小范围。看来这里的大多数答案都是针对dpkg / apt的,因此对于rpm / yum一个单独的问题可能有意义。
夸克

切换到NixOS:)(只需拖曳)。
Alexey'2

Answers:


31

在任何基于Debian的机器上,这是复制软件包集的一种常用方法。在旧机器上:

dpkg --get-selections "*" > my_favorite_packages

将文件复制my_favorite_packages到新计算机(拇指驱动器是一个不错的选择,但scp也可以正常工作)。然后运行以下序列(具有root特权):

apt-get update
dpkg --set-selections < my_favorite_packages
apt-get -u dselect-upgrade

这并不能使您获得已安装的软件包。它还会获取它们的依赖关系,等等。此外,如果两台计算机之间的存储库不同,则所有选择都将关闭。

至于日志,请apt-get保留日志/var/log/apt/history.log(感谢Tshepang在评论中进行更新);dpkg(在处/var/log/dpkg.log),但是众所周知,它很难解析,并且只能以root权限读取;aptitude有一个,/var/log/aptitude您可以使用常规用户权限翻页。

据我所知,您是正确的,这些日志都没有专门跟踪您安装的内容,而不是自动安装的依赖项。但是,您可以通过aptitude搜索获得该信息。搜索所有已自动安装的已安装软件包:

aptitude search '~i ~M'

如果需要安装的内容(而不是自动依赖项),请取消~M

aptitude search '~i !~M'

如果希望将其格式化为包含软件包名称和单词“ install”,则aptitude也可以这样做。这为您提供了准备送入的列表dpkg --get-selections

aptitude search '~i !~M' -F "%p install"

(在RedHat或基于RedHat的系统上我什么都没有。对不起。Linux 本身并没有一个答案,因为软件包管理是使不同发行版有所不同的很大一部分。)


似乎您的建议和路德维希的建议相结合可以解决问题:aptitude可以生成一个脚本来馈送给dpkg,因此这是可自动化的,这是一个巨大的胜利。如果要在香草机上进行操作,列表上的差异与我所要求的实用范围非常接近。
夸克

3
请注意,APT现在会记录在“/var/log/apt/history.log”,以及所使用的apt-getsynaptic以及aptitude(就我所看到)。这是自2010年初
tshepang

这些dpkg.log声明在Ubuntu 14.04中似乎并不正确,因为我可以轻松,不琐碎但不太困难地选择我的用户。awk '$3 != "install" { next } ; { gsub(/:.+/, "", $4) ; print $4 }' /var/log/dpkg.log | sort | uniq
Steve Buzonas 2015年

实际上,我意识到这并不像我最初想象的那么容易,以前的awk脚本中的缺陷没有注意卸载的软件包。以下awk '$3 !~ /install|remove|purge/ { next } { gsub(/remove|purge/, "uninstall", $3) ; gsub(/:.+/, "", $4) ; a[$4]=$3 } END { for (p in a) { if (a[p] == "install") { print p } } }' /var/log/dpkg.log | sort -u是。
Steve Buzonas 2015年

7

使用dpkg -l '*' > jaunty.original到remeber一个新安装的系统上所有已安装的软件包。

安装完所有其他软件包之后dpkg -l '*' > mysystem.2009017

其他软件包只是不同之处: diff jaunty.original mysystem.2009017


3
基本思想很强:使用命令行转储当前安装的应用程序列表,然后使用命令行在新计算机上安装这些软件包。您可以通过该方法获得相当有创意和特定性。
pcapademic

1
我更喜欢dpkg --get-selections
CesarB

尽管这不能跟踪我添加的软件包(与它们的依赖项不同),但它肯定会生成一个有用的列表。
夸克

3

实际上,Aptitude非常擅长于此。Aptitude确实知道何时手动安装或通过依赖项进行安装,并且您可以告诉它删除不再需要的安装项,而仅仅是因为其他依赖于此的项总是使您的系统尽可能小。

有一些软件包可以组成Ubuntu安装,最小的ubuntu,桌面的ubuntu,服务器的ubuntu等。如果您告诉Aptitude将其标记为手动安装并删除其他所有内容,那么最终您将获得尽可能少的软件包。

我在博客的两篇文章中解释了如何做到这一点:清理Debian GNU / Linux清理Debian GNU / Linux(或Ubuntu),reprise。简而言之,您正在寻找的答案是:

aptitude search ~i | grep -v "i A"

我上一次使用它时,如果您使用apt-get,则它不起作用。这就是为什么我总是推荐aptitude的原因,据我所知,Debian不赞成apt-get来支持aptitude。

我不知道如何在Fedora上执行此操作,您可能应该将其分开而不是一个不同的问题。Fedora和Ubuntu是不同的操作系统,因此应将其视为同一操作系统(即使它们共享内核和其他内容)。


2
我认为您可以获取信息,而无需grep:可以解决问题aptitude search '~i !~M'
Telemachus

1
另外,apt-get不建议弃用。Debian建议aptitude在命令行上进行软件包管理,但这与弃用相差甚远apt-get
Telemachus

这里有些微妙。在第三列中寻找“ A”似乎确实标记了我知道已安装为依赖项的软件包。但这显然并没有抓住所有问题:我明确提出的请求中肯定没有安装大多数列表。
夸克

@Telemachus。您的命令和带有模式的命令的功能并不完全相同:两个列表的内容不同。我对智能并不了解,但是告诉你为什么。
夸克

@Pablo:您的日志链接似乎已断开。如果您能解决它们,我一定会阅读它们。
夸克


1

在基于apt的系统上,请查看/var/log/apt/term.log。对我来说,有一条清晰的线可以画出安装的结束位置和安装的开始位置。


对我来说不太有用,因为手动安装和系统更新混在一起。另外,取决于您的设置期限。logs最终将过时并被删除,因此不会回溯到我需要的程度。
夸克

对于任何尝试此操作的人,请注意,涉猎apt的日志似乎比这里讨论的其他选项要耗费大量精力。从日志中提取软件包列表当然不是自动的。
夸克

1

来自man aptitude-create-state-bundle

aptitude-create-state-bundle生成一个压缩的存档,其中存储了复制当前程序包存档状态所需的文件。

这将保留与aptitude手动安装哪些软件包相同的信息。

它旨在与aptitude-run-state-bundle

aptitude-run-state-bundle将由aptitude-create-state-bundle(1)创建的给定aptitude状态包解压缩到一个临时目录,使用提供的对其进行调用,然后删除该临时目录。


1

仅在使用时,dpkg您不知道该软件包是由用户手动安装还是由用户自动安装(作为依赖项或在初始OS安装过程中)。如果要保留该信息,则仅需要获取实际手动安装的软件包的列表。

为此,您可以使用这两个单线之一。两者在我的机器上都能产生完全相同的输出,并且比到目前为止在此问题中提出的所有解决方案都更精确。它们是两个答案(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)

极少数仍然包通过裂缝下跌,虽然我怀疑这由用户实际安装,通过语言本地化设置或安装例如,通过编解码器图腾安装程序后,无论是正确的。另外,即使我仅安装了非特定于版本的metapackage,Linux标头版本也似乎在累积。例子:

libreoffice-help-en-gb
openoffice.org-hyphenation
gstreamer0.10-fluendo-mp3
linux-headers-3.13.0-29    

它是如何工作的

  1. 获取手动安装的软件包的列表。为了适应性强,其他sed行将去除行尾的剩余空白。
  2. 全新安装后,立即获得已安装软件包的列表。
  3. 比较文件,仅输出文件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.gzapt-mark例如,不包含xserver-xorg软件包,而另一个文件包含。

两者都列出了比上述解决方案更多的软件包。


0

我有偏见,我提出的解决方案并非总是可行的,但是我对这种情况感到厌倦。结果是我不再使用更新/程序包管理器工具安装任何东西。

不过,我走了一条相当艰难的路(我对版本有严格的要求)。我创建了一个巨大的makefile,可以将我需要的每个程序包(程序,库等)下载,编译和安装在主目录中。我一步一步地开发它。Makefile下载并编译所有内容,甚至包括编译器。

当我转移到新系统或重新安装时,只需复制makefile(加上一些支持的东西),运行make world并在第二天回来。

对于我开发的某些程序(我可以控制),我使用自己编写的工具栗子软件包管理器。在MacOSX上有点像.app文件夹。一切都在软件包中,因此我随时知道安装了什么,并且知道它是自包含的并且自给自足(系统库除外)


您可以将软件包管理器的安装命令放入脚本中,并且具有相同的效果。假设您需要的代码已打包。您的方法看起来与gentoo的方法非常相似。
wcoenen

很高兴知道。除了默认的Ubuntu / Debian系统,看起来还有很多额外的工作。我可以看到手动维护一些软件包,但是以这种方式维护所有软件包比我想做的工作更多。
夸克

是的,但是还有一个额外的问题,就是ubuntu / fink / darwinports的东西不能在所有平台上都跨平台工作(我曾经使用过数字和IBM sp4)。我不认为这是个不错的选择。我只是说它可以完成工作,尽管以丑陋,有臭味的方式进行,而且我可以完全控制系统中发生的事情。
Stefano Borini,2009年

当然,我可以决定在其中的某一天里认真看待出现并对其进行重新处理。
Stefano Borini,2009年

这些天来,当您考虑使用厨师和木偶之类的工具时,这种路径更为常见。
史蒂夫·布佐纳斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.