问题描述
我想获得由apt
或aptitude
手动安装的软件包列表,并能够找出foobar
软件包是手动安装还是自动安装。有没有从命令行做到这一点的干净方式?
最佳解决方案
您可以使用这两个one-liners中的任何一个。两者在我的机器上产出完全相同的输出,并且比迄今为止(2014年7月6日)提出的所有解决方案都更精确。
使用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)
尽管我怀疑这些包实际上是由用户安装的,或者在安装之后通过语言本地化设置或者例如通过图腾编解码器安装程序。此外,linux-header版本也似乎积累,即使我只安装了非version-specific元组件。例子:
libreoffice-help-en-gb
openoffice.org-hyphenation
gstreamer0.10-fluendo-mp3
linux-headers-3.13.0-29
它是如何工作的:
-
获取手动安装的软件包列表。为了适应能力,额外的
sed
去除行尾的剩余空白。 -
获取全新安装后安装的软件包列表。
-
比较文件,只输出文件1中不存在于文件2中的行。
其他可能性也不适用:
-
使用
ubuntu-14.04-desktop-amd64.manifest
文件(用于Ubuntu 14.04的here)而不是/var/log/installer/initial-status.gz
。尽管没有,更多的软件包显示为手动安装。 -
使用
apt-mark showauto
而不是/var/log/installer/initial-status.gz
。apt-mark
例如不包含xserver-xorg包,而另一个文件包含。
我使用各种其他StackExchange职位作为参考,但没有工作以及上述解决方案:
都列出比上述解决方案更多的软件包。
编辑:如果您从以前的版本升级,该怎么做:
如果您已将Ubuntu从一个版本升级到下一版本,则可能需要调整此过程。在这种情况下,除了当前版本的initial-status.gz文件外,我还要检查新版本的清单文件(参见上文)。只需添加另一个比较即可轻松完成此操作。只使用清单文件将不起作用,因为清单文件不幸并不包含initial_status.gz文件(我选中)所做的所有内容。
次佳解决方案
在apt的新版本中,还有apt-mark命令
apt-mark showmanual
第三种解决方案
如果包自动安装,apt-mark showauto | grep -iE '^foobar$'
将输出”foobar”,否则不会。
aptitude search '!~M ~i'
将列出未自动安装的软件包。可惜aptitude从10.10开始不会成为Ubuntu桌面上默认安装的一部分。
第四种方案
以下脚本将打印出所有未设置为自动安装的软件包,因此已手动安装:
#!/usr/bin/python
try:
import apt_pkg
except ImportError:
print "Error importing apt_pkg, is python-apt installed?"
sys.exit(1)
apt_pkg.init()
STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
auto = set()
tagfile = apt_pkg.TagFile(open(STATE_FILE))
while tagfile.step():
pkgname = tagfile.section.get("Package")
autoInst = tagfile.section.get("Auto-Installed")
if not int(autoInst):
auto.add(pkgname)
print "\n".join(sorted(auto))
它基于apt-mark如何打印自动安装的软件包。
第五种方案
对于Ubuntu 16.04,请查看日志文件/var/log/apt/history.log
。
例如:
zgrep 'Commandline: apt' /var/log/apt/history.log /var/log/apt/history.log.*.gz
这并不完美,但它很好地清楚了我手工安装的内容。将一个-B 1
放在grep上以查看它的安装时间。
示例输出
Commandline: apt install postgresql-9.5-plv8
Commandline: aptdaemon role='role-install-file' sender=':1.85'
Commandline: apt install task
Commandline: apt autoremove
Commandline: apt install atom
Commandline: apt upgrade
Commandline: apt-get install asciinema
Commandline: apt install iperf3
Commandline: apt upgrade
Commandline: apt-get install chromium-browser
Commandline: apt install joe cpanminus build-essential postgresql libdbd-pg-perl libcrypt-openssl-bignum-perl libcrypt-openssl-rsa-perl libio-socket-ssl-perl libnet-ssleay-perl libssl-dev
Commandline: aptdaemon role='role-commit-packages' sender=':1.2314'
Commandline: apt install git
Commandline: apt install sqlite
Commandline: apt install whois
Commandline: apt install libdbd-pg-perl
Commandline: apt install perl-doc
Commandline: apt upgrade
不知道这是否挑选aptitude
或不。它似乎没有从Ubuntu软件桌面应用程序中选择安装。
第六种方案
正如几位人士所评论的,apt-mark showmanual似乎有点错误(我把它报告为bug 727799)。当我使用它时,它实际上报告了很多甚至没有记录在/var /lib /apt /extended_states(其中应该存储的地方)的内容,而apt-get没有记录安装在/var中的东西/lib /apt /extended_states(只在/var /lib /dpkg /status中)。上面的txwikinger的python脚本直接从/var /lib /apt /extended_states中绘制,但如果今天使用它,语法可能不起作用(我的Kubuntu 13.10开始产生错误)。更新的语法是:
#!/usr/bin/python
import sys
try:
import apt_pkg
except ImportError:
print "Error importing apt_pkg, is python-apt installed?"
sys.exit(1)
apt_pkg.init()
STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
auto = set()
tagfile = apt_pkg.TagFile(open(STATE_FILE))
while tagfile.step():
pkgname = tagfile.section.get("Package")
autoInst = tagfile.section.get("Auto-Installed")
if not int(autoInst):
auto.add(pkgname)
print "\n".join(sorted(auto))
对我来说,这是一个非常短的5个项目,看起来并不准确。
第七种方案
要获取所有软件包的列表(未安装,由用户安装或默认安装,跨所有PPA),apt
采用以下方法:
apt list [option]
对此有用的可能选项是:
--installed
仅显示系统上安装的软件包(大约50,000以上)
--manual-installed
可以列出由命令显式安装的包,可以是直接包含的,也可以是依赖包。
或者,你可以这样做:
apt list --manual-installed | grep -F \[installed\]
以获取仅由用户命令及其依赖关系产生的软件包列表,并获取有关它们的其他信息,例如支持的版本和体系结构(x86,x86_64,amd64,all等)