it-swarm.cn

生成手动安装的包列表并查询各个包

我想获得由aptaptitude手动安装的软件包列表,并能够找出是否手动或自动安装了foobar软件包。从命令行有没有任何巧妙的方法?

182
Umang

您可以使用这两个单行中的任何一个。两者在我的机器上产生完全相同的输出,并且比在此问题中直到现在(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)

虽然我怀疑这些实际上是由用户安装的,或者在通过语言本地化设置安装之后,或者例如安装,但是很少有软件包仍然存在。通过Totem编解码器安装程序。此外,linux-header版本似乎也在积累,即使我只安装了非特定于版本的元数据包。例子:

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

它是如何工作的:

  1. 获取手动安装的包列表。对于aptitude,附加的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.gz。例如apt-mark不包含xserver-xorg包,而另一个文件包含xserver-xorg包。

我使用了各种其他StackExchange帖子作为参考,但是没有一个像上面的解决方案一样好用:

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

编辑:如果你从之前的版本升级怎么办:

如果您已将Ubuntu从一个版本升级到下一个版本,则可能需要调整此过程。在这种情况下,除了当前版本的initial-status.gz文件之外,我还会检查较新版本的清单文件(参见上文)。只需添加另一个比较,您就可以轻松完成。仅使用清单文件将不起作用,因为清单文件遗憾地不包含initial_status.gz文件所做的一切(我已检查过)。

205
jmiserez

在apt的较新版本中,还有apt-mark命令

apt-mark showmanual
64
Daniel Alder

对于Ubuntu 16.04,请查看日志文件/var/log/apt/history.log

例如:

zgrep 'Commandline: apt' /var/log/apt/history.log /var/log/apt/history.log.*.gz

它并不完美,但它非常擅长清楚地说明我手工安装的内容。在grep上放一个-B 1以查看它的安装时间。

示例输出

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软件桌面应用程序中获取安装。

21
s1037989

如果包是自动安装的,apt-mark showauto | grep -iE '^foobar$'将输出“foobar”,否则没有。

aptitude search '!~M ~i'将列出未自动安装的软件包。从10.10开始,这可能不会成为Ubuntu桌面上默认安装的一部分。

20
Li Lo

以下脚本将打印出未设置为自动安装的所有软件包,因此已手动安装:

#!/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如何打印自动安装的包。

8
txwikinger

要获取所有软件包的列表(未安装,由用户安装或默认安装,跨所有PPA),apt使用以下方法:

apt list [option]

对此有用的可能选项包括:

--installed仅显示系统上安装的软件包(大约50,000+)

--manual-installed列出直接或作为依赖项由命令显式安装的软件包。

或者,您可以这样做:

apt list --manual-installed | grep -F \[installed\]获取仅由用户命令及其依赖项产生的包列表,并获取有关它们的其他信息,例如支持的版本和体系结构(x86,x86_64,AMD64,all等)

6
Aalok

有几个人评论说,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个项目列表,似乎也不准确。

5
cluelesscoder

我想提供一个GUI解决方案。

enter image description here

  1. 打开Synaptic Package Manager

  2. 转到Status

  3. 单击Installed (manual)

它将给出apt或aptitude手动安装的软件包列表。

不幸的是,我在Custom Filters中找不到任何选项来查明是否手动或自动安装了foobar包。

如果包在Installed下但不在Installed (manual)下,则它自动安装。如果包在Installed (manual)下,则手动安装。

4
blueray

如果没有人使用apr-something命令给你一个很好的答案你可以做到艰难的方式。 Apt-get将其信息存储在/ var/lib/apt/extended_states中。自动安装的任何文件都将添加到此文件中。如果您手动安装此文件中的软件包,该软件包将保留在此文件中,但在第二行中使用自动安装:0。它没有被删除。

注意:正如预期的那样,如果出现文件放置更改,可能会有更好的答案。我保留我的以防万一文件位置的信息很有用。

2
Javier Rivera

经过Google搜索后,我设法组装了这个脚本。它适合我:

# List of all packages currently installed
current=$(dpkg -l | awk '{print $2}' | sort | uniq)

# List of all packages that were installed with the system
pre=$(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort | uniq)

# List of packages that don't depend on any other package
manual=$(apt-mark showmanual | sort | uniq)

# (Current - Pre) ∩ (Manual)
packages=$(comm -12 <(comm -23 <(echo "$current") <(echo "$pre")) <(echo "$manual") )

for pack in $packages; do
    packname=$(echo $pack | cut -f 1 -d ":")
    desc=$(apt-cache search "^$packname$" | sed -E 's/.* - (.*)/\1/')
    date=$(date -r /var/lib/dpkg/info/$pack.list)

    echo "# $desc"
    echo "# $date"
    echo "Sudo apt-get install $pack"
    echo -e ""
done
2
dufferZafar

正如Li Lo所说,apt-mark showauto应该会为你提供一个自动安装的大量内容。

现在为了展示手动安装的东西,事实证明,aptitude有一个可爱的简单搜索修改器。但你不想这样做。你想写一个巨大的bash命令来做一些火箭科学。

注意:这更像是一个很酷的例子,你会看到对你所有的朋友大肆宣传大量的bash命令。

comm -3  <(dpkg-query --show -f '${Package} ${Status}\n' | \n
grep "install ok installed" | cut --delimiter=' ' -f 1) <(apt-mark showauto)

为了便于阅读,我把它分成两行。这是做什么的?

  • 首先,我们查询dpkg以获取已安装的软件包列表。
  • 我们过滤那些实际安装的(不只是残留配置)
  • 我们砍掉了地位
  • 我们将该列表与apt-mark中的自动列表进行比较
  • 我们摇滚乐,因为我们可以。
1
Oli