54

How can I list all packages I've installed from a particular repository?

How can I list all installed packages that are not available from the main Ubuntu archives, and also see which repositories they came from? (If I knew the answer to this question, I could grep that list for a particular PPA name to find out the answer to my first question.)

1
  • Since there doesn't seem to be an existing command-line tool for this (sadly), I'll accept one of the GUI answers. Oct 15 '10 at 0:07
28

There seems to be no record of the origin of an installed package.

If you are fine with getting the location from whence a package of the same name would be downloaded from, this is available through apt-cache policy. The following (rather ugly) script does the trick for me:

LC_ALL=C dpkg-query --showformat='${Package}:${Status}\n' -W '*' \
  | fgrep ':install ok installed' \
  | cut -d: -f1 \
  | (while read pkg; do 
       inst_version=$(apt-cache policy $pkg \
                                | fgrep Installed: \
                                | awk '{ print $2 }'); 
       origin=$(apt-cache policy "$pkg" \
                          | fgrep " *** ${inst_version}" -C1 \
                          | tail -n 1 \
                          | cut -c12-); 
       echo $pkg $origin; 
     done)

Note that it's quite fragile, as it makes assumptions about the output of apt-cache policy, which might change across versions...

3
  • Yeah, this would basically mean writing a tool from scratch. And I think parsing /var/lib/apt/lists with Perl or Python would be faster and more robust. Oct 15 '10 at 0:07
  • Works normally here, in 2018 :) Thank you!
    – N0rbert
    Mar 5 '18 at 7:25
  • I developed a similar solution tested on Ubuntu and Debian.
    – famzah
    Apr 24 '18 at 18:23
23

Expand the "Installed Software" item in Ubuntu Software Center. You'll see a list of all the different repositories that you've enabled. Clicking on the repo will show you the packages you've installed from each.

alt text

3
  • I'm afraid that option is only available in Ubuntu 10.10 or am I missing something? My Software Center doesn't display sources below that menu. Oct 11 '10 at 15:17
  • 2
    In my version I have an "Installed" dropdown at the top. When I select that option, I can choose the various sources (core, for purchse, PPA...) Oct 29 '14 at 6:06
  • In Ubuntu 16.04, this page is no longer available. However, synaptic has a similar feature -- click "Origin" in the bottom-left.
    – Ash
    Apr 9 '17 at 8:48
23

Open Synaptic Package Manager and click the "Origin" button on the bottom of the left sidebar. It will list your sources. Select a source to see the available/installed packages.

4

This script lists packages that are installed and available in the PPA:

#!/bin/sh
# Give PPA name as an argument, e.g. ppa:oibaf/graphics-drivers

name1="$(echo "$1"|cut -d: -f2|cut -d/ -f1)"
name2="$(echo "$1"|cut -d/ -f2)"

awk '$1 == "Package:" { if (a[$2]++ == 0) print $2; }' \
/var/lib/apt/lists/*"$name1"*"$name2"*Packages |
xargs dpkg-query -W -f='${Status} ${Package}\n' 2>/dev/null  | awk '/^[^ ]+ ok installed/{print $4}'

I applied this.

BTW, as for removing PPA from use, use ppa-purge program; I have created an improved version of it here.

3

Under Quantal (12.10), the space in the origin line needs to be removed.

LC_ALL=C dpkg-query --showformat='${Package}:${Status}\n' -W '*' \
 | fgrep ':install ok installed' \
 | cut -d: -f1 \
 | (while read pkg; do 
   inst_version=$(apt-cache policy $pkg \
                            | fgrep Installed: \
                            | cut -d: -f2-); 
   origin=$(apt-cache policy "$pkg" \
                      | fgrep " ***${inst_version}" -C1 \
                      | tail -n 1 \
                      | cut -c12-); 
   echo $pkg $origin; 
 done)
0
2

If you have a system without a Wayland/X server (like a Raspberry Pi), the answers of andrewsomething and lovinglinux cannot be used. The answer of jarno limits the use case to PPAs only, although the question is of general interest. The scripts from Riccardo Murri and Graham Dunn are quite slow due to the repeated apt-cache policy calls (like about 10 minutes runtime).

So this is my call solving the general case on a shell being a lot faster (like less than 10 seconds runtime)

apt list --installed 2> /dev/null \
  | cut -d/ -f1 \
  | parallel -n200 apt-cache policy \
  | rg '^(\S+)[\s\S]+?\* (?:\S+\s+){3}(\S+)' -Uor '$1 $2'

apt list --installed gets a list of all installed packages ignoring apt's message about possible future format changes with 2> /dev/null and extracting only the package names with cut by using / as a delimiter with -d/ and returning the first field with -f1.

Then, apt-cache policy is used to get more information about all the packages. This could be executed with xargs, as apt-cache expects its input as command line argument. As this is the remaining performance-critical part, GNU parallel from package parallel is used instead to run multiple apt-cache processes in parallel looking up 200 packages with each using -n200. Note, that xargs can run multiple commands in parallel, too, but synchronizes output on newline, which is not correct here in general.

Finally, apt-cache's output is parsed with rg from package ripgrep which is a very fast and multiline capable grep successor with -U allowing to output two regular expression capture groups with -or '$1 $2'. The regular expression captures the package name with ^(\S+), skips to the last star marking the installed repository with [\s\S]+?\* , then skips three words with (?:\S+\s+){3} and finally captures the repository with (\S+).

1

Something like this Python script should find all non-Ubuntu packages installed on your machine:

#!/usr/bin/env python3
#
# This lists all packages not from Ubuntu's (e.g. main/universe) repositories
# To use, simply download/copy into a .py file and run with:
# python3 list_non_ubuntu.py
#
# If you receive an import error, you may need to install python3-apt first with e.g.
# sudo apt install python3-apt
# but this is often not necessary

import apt


cache = apt.Cache()
package_count = 0

for package in cache:
    if (
        package.is_installed
        and package.candidate.origins[0].origin != "Ubuntu"
    ):
        package_origin = package.candidate.origins[0]
        print(
            package.name,
            # See https://apt-team.pages.debian.net/python-apt/library/apt.package.html#apt.package.Origin
            # for further details on the meanings of the below
            package_origin.origin,  # The Origin, as set in the Release file
            package_origin.archive,  # The archive (eg. Ubuntu release name)
            package_origin.component,  # The component (eg. main/universe)
            package_origin.site,  # The hostname of the site.
            # package_origin.label,  # The Label, as set in the Release file
            # package_origin.trusted,  # Origin trusted (Release file signed by key in apt keyring)
        )
        package_count += 1

print(package_count, "packages not from Ubuntu")

On my machine this took under 5 seconds to run, compared to over 8 minutes for the current top answer (from Riccardo/Pablo). Output is in the format:

$ python3 list_non_ubuntu.py 
azure-cli azure-cli focal focal main packages.microsoft.com
google-chrome-stable Google LLC stable main dl.google.com
[...]
signal-desktop . xenial xenial main updates.signal.org
8 packages not from Ubuntu

You could then add an additional and package.candidate.origins[0].site == "[ppa-domain.com]" after the .origin != "Ubuntu" if you only want ones from a particular ppa.

2
  • 1
    This is neat! I think you need python3-apt rather than python-apt. BTW is there a reason to use cache[package.name].is_installed instead of package.is_installed? Aug 2 at 13:05
  • Both good suggestions, thanks @MariusGedminas -- I have changed. Aug 3 at 18:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.