如何列出所有从PPA安装的软件包?

我在我的系统上安装了许多来自不同PPA的软件包。我想列出所有从launchpad PPA安装的软件包,而不是仓库中的软件包。
这个能通过命令行实现吗?

可能是重复的问题吗?http://askubuntu.com/questions/43581/how-to-list-packages-from-a-ppa-source-in-command-line - Mitch
不,这是另外一个。 - Avinash Raj
1不是一个命令行实用程序,但非常有用的是Y PPA Manager。它可以列出、安装和删除来自PPA的软件包。 - Jos
从给定的PPA中:http://askubuntu.com/questions/5976/how-can-i-list-all-packages-ive-installed-from-a-particular-ppa - Ciro Santilli OurBigBook.com
6个回答

以下命令返回软件包名称及其ppa(如果从ppa安装):
apt-cache policy $(dpkg --get-selections | grep -v deinstall$ | awk '{ print $1 }') | perl -e '@a = <>; $a=join("", @a); $a =~ s/\n(\S)/\n\n$1/g;  @packages = split("\n\n", $a); foreach $p (@packages) {print "$1: $2\n" if $p =~ /^(.*?):.*?500 http:\/\/ppa\.launchpad\.net\/(.*?)\s/s}'

细节:

  • dpkg --get-selections 只返回已安装的软件包,排除了 grep -v deinstall$
  • awk '{ print $1 }' 只返回软件包名称
  • perl -e '@a = <>; $a=join("", @a)'apt-cache policy 返回的所有行连接起来
  • $a =~ s/\n(\S)/\n\n$1/g; 在每个软件包部分之间添加一个换行符
  • @packages = split("\n\n", $a); 是一个包含所有软件包信息的 Perl 数组,每个软件包占据一个项目。
  • foreach $p (@packages) {print "$1: $2\n" if $p =~ /^(.*?):.*?500 http:\/\/ppa\.launchpad\.net\/(.*?)\s/s} 是一个循环,如果在策略中找到优先级为 500 的 ppa,则打印出软件包和 ppa。

短答案/代码,执行时间很长。 - Radu Rădeanu


1aptitude 的另一个酷炫功能 +1 - Ravexina
@user.dz 在我的Ubuntu上,aptitude显示:E: 匹配模式意外结束(预期为')')。 - SebMa
@SebMa,我刚刚在https://linuxcontainers.org/lxd/try-it/上的在线LXD容器(Ubuntu 18.04.4 LTS)中尝试了一下,它运行得很好。你使用的是哪个shell?请确认你是否使用相同的字符串限定符,如'string' - user.dz
1@user.dz 对不起,我之前有一个有 bug 的 aptitude shell 函数。你的命令现在在我的系统上可以运行了。非常感谢 :) - SebMa

可以使用apt-cache来检查已安装软件包的来源,例如: $ apt-cache policy oracle-java7-installer
oracle-java7-installer:
  Installed: 7u51-0~webupd8~7
  Candidate: 7u51-0~webupd8~7
  Version table:
 *** 7u51-0~webupd8~7 0
        500 http://ppa.launchpad.net/webupd8team/java/ubuntu/ precise/main i386 Packages
        100 /var/lib/dpkg/status

apt-cache policy <package_name> 的输出包含源代码。

可以使用以下脚本获取从 PPAs 安装的软件包列表。

#!/bin/bash
echo "List of packages which are not installed from Ubuntu repository"
for i in `dpkg -l | grep "^ii" | awk '{print $2}'`
do
    j=`apt-cache policy "$i" | grep "ppa.launchpad.net"` 
    if [ $? -eq 0 ]; then
        echo "$i"
        #echo "$i $j"
    fi
done

1如果您选择了不同的镜像,它就无法工作。例如,我有gir1.2-syncmenu-0.1 500 http://ubuntu.univ-nantes.fr/ubuntu/ saucy/main amd64 Packages - Sylvain Pineau
在这种情况下,google-chrome-stable并不是通过PPA安装的;它只有一个独立的软件源。 - Radu Rădeanu
1好的,我看到了。但是你给出了一个非常糟糕的例子,可能会让新手用户误以为如果一个软件包不来自Ubuntu软件仓库,那么它就来自PPA。OP的问题是关于PPA的。 - Radu Rădeanu
@RaduRădeanu 我明白你的观点并且修改了我的帖子。你是完全正确的。 - sourav c.
现在好多了,尽管执行时间有点长,但问题已经解决了。 - Radu Rădeanu

根据这个答案这篇帖子,你可以使用以下bash代码获取系统上安装的所有PPA的软件包列表:
for APT in $(find /etc/apt/ -name \*.list); do
  grep -o "^deb http://ppa.launchpad.net/[a-z0-9\-]\+/[a-z0-9\-]\+" $APT | while read ENTRY ; do
    USER=$(echo $ENTRY | cut -d/ -f4)
    PPA=$(echo $ENTRY | cut -d/ -f5)
    awk '$1 == "Package:" { if (a[$2]++ == 0) print $2; }' /var/lib/apt/lists/*$USER*$PPA*Packages
    done
done

根据这个答案,你可以使用以下命令获取系统中安装的所有软件包的列表:
dpkg --get-selections | grep -v deinstall | cut -f1

现在,让我们将这两个想法结合起来,以获取所有从PPA安装的软件包列表。
(for APT in $(find /etc/apt/ -name \*.list); do
  grep -o "^deb http://ppa.launchpad.net/[a-z0-9\-]\+/[a-z0-9\-]\+" $APT | while read ENTRY ; do
    USER=$(echo $ENTRY | cut -d/ -f4)
    PPA=$(echo $ENTRY | cut -d/ -f5)
    awk '$1 == "Package:" { if (a[$2]++ == 0) print $2; }' /var/lib/apt/lists/*$USER*$PPA*Packages
    done
done; dpkg --get-selections | grep -v deinstall | cut -f1) | sort | awk 'dup[$0]++ == 1'

安装synaptic。然后,您可以通过“来源”或任何其他自定义筛选器浏览软件包。

我想知道每个ppa有多少个软件包,所以我稍微修改了Sylvain的精彩答案:
apt-cache policy $(dpkg --get-selections | grep -v deinstall$ | awk '{ print $1 }') \
| perl -e '@a = <>; $a=join("", @a); $a =~ s/\n(\S)/\n\n$1/g;  @packages = split("\n\n", $a); foreach $p (@packages) {printf "%-40s %s\n", $2, $1 if $p =~ /^(.*?):.*?500 http:\/\/ppa\.launchpad\.net\/(.*?)\s/s}' \
| sort \
| uniq -c -w 40

通过首先打印ppa并且只使用前40个字符来计数和去重,我可以得到这样的输出:
  5 alexlarsson/flatpak/ubuntu               flatpak
147 bleedingedge/focal-bleed/ubuntu          bzip2
  1 justinabrahms/ttf-cascadia-code/ubuntu   ttf-cascadia-code
 44 libreoffice/ppa/ubuntu                   fonts-opensymbol
 71 savoury1/backports/ubuntu                bash
 41 savoury1/multimedia/ubuntu               dav1d
  8 strukturag/libheif/ubuntu                aom-tools
 12 ubuntugis/ubuntugis-unstable/ubuntu      gdal-bin