4

Is it possible to list all installed packages from a specific official repository component (Main, Restricted, Universe or Multiverse) using utilities like apt, apt-cache, aptitude?

I wrote a simple script for this purpose:

dpkg -l | grep ^ii | cut -f3 -d ' ' | while read -r pkg;
do
 status=`apt-cache show $pkg | grep -m1 "Section: multiverse"`
 if [ ! -z "$status" ] 
 then
  echo $pkg
 fi
done;

It works, but it's really slow cause it's checking all packages one by one. Running the time command for this script will produce:

real    1m16.797s
user    0m57.008s
sys     0m8.260s

I already tried aptitude search patterns, and dpkg-query formating, but it seems they don't have the proper column/schema to create a query for this purpose.

I also had a look at vrms script to find out how it's works, because it's really fast in finding contrib/non-free packages, it's seems that vrms script scans the whole /var/lib/dpkg/status file, looking for things like 'Section: (contrib | non-free | restricted | multiverse | partner )', so it wasn't helpful either, because not all packages have this section.

3 Answers 3

2

Okay, I didn't found any solution to do this with standard utilities, however after having a look at vrms I came-up with a pretty better script to search for packages installed from a specific component.

The other script which I mentioned in my question was really time consuming.
However, the new script is available here: pkgs-from.sh

The usage is:

./pkgs-from.sh universe # or main, multiverse, backports

And the time command result for this one is:

real    0m4.367s
user    0m0.980s
sys     0m0.408s

Which is pretty good.

How it works?
The script will create a list of all packages related to the requested component from related files within the /var/lib/apt/lists/ directory, then starts to search throughout them instead of using apt-cache.

0
2

Adding a Python script for any who prefer that approach:

import apt


cache = apt.Cache()
package_count = 0

for package in cache:
    if (
        cache[package.name].is_installed
        and package.candidate.origins[0].origin == "Ubuntu"
        and package.candidate.origins[0].component == "universe"
    ):
        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 from Ubuntu universe")

Speed should be in seconds, rather than the minutes that piping the installed package list to apt-cache policy takes

0

Here my script to monitor installed packages for a given component

FILTER=non-free TMP_DIR=$(mktemp -d) && {
  dpkg -l | grep ^ii | cut -f 3 -d' ' | cut -f 1 -d : | sort | uniq > ${TMP_DIR}/pkg_installed.list
  cat /var/lib/apt/lists/*_${FILTER}_*Packages | grep "^Package:"  | sort | uniq | cut -d' ' -f2 > ${TMP_DIR}/pkg_filtered.list
  comm -12 ${TMP_DIR}/pkg_installed.list ${TMP_DIR}/pkg_filtered.list
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .