6

As explained in Ubuntu documentation / Repositories:

Software in Ubuntu's repository is divided into four categories or components - main, restricted, universe and multiverse.

Is there a simple method to list all the installed software together with the repository component (main, restricted, universe and multiverse) on an Ubuntu system?

Sample output:

...
apt                    main
apt-file               universe
libnvidia-common-570   restricted
virtualbox             multiverse
chrome-gnome-shell     unknown
...
FedKad
  • 13,900
  • There are many thousands of packages installed onto a typical Ubuntu system, so the list will be rather long. – user535733 Jul 16 '25 at 03:05

2 Answers2

8

The component is a part of the repository. A package could be available in any number of components in any number of repositories, so given just a package, in general it's not possible to say which component or repository it came from. However, you can list which component it is currently available from, by using, say, the Python apt library:

#! /usr/bin/python3
import apt

cache = apt.Cache() packages = [package for package in cache if package.installed] for package in packages: print(f"{package.shortname}\t{package.candidate.origins[0].component}")

Save this in a file, and execute it. Example output:

# python3 foo.py  | column -t | head
7zip                   universe
apt                    main
base-files             main
base-passwd            main
bash                   main
bsdextrautils          main
bsdmainutils           universe
bsdutils               main
coreutils              main
dash                   main

You could also parse the output of apt-cache policy for this information (it will also list the component of the candidate versions). The above script has no error checking, which you might need to add if some package has no installation candidate.

muru
  • 207,970
  • Will this show multiple entries if the package can be found in more than one place? I'm guessing it won't, right? – terdon Jul 16 '25 at 09:10
  • Nope. I'm picking the first origin available (origins[0]), though we could loop over origins and print all components, with something like {" ".join([origin.component for origin in package.candidate.origins])} – muru Jul 16 '25 at 09:14
4

@muru's answer is OK and fast.

However, with the help of an AI, I was able to design another similar answer in pure Bash:

#!/bin/bash
dpkg-query -f '${Status} ${Package}\n' -W | 
awk '$1 == "install" && $2 == "ok" && $3 == "installed" {print $4}' | 
while read -r pkg; do
  component=$(apt-cache show "$pkg" 2>/dev/null | 
    grep -m1 ^Filename: | 
    grep -oE '/(main|universe|restricted|multiverse)/' | tr -d '/')
  printf "${pkg}\t${component:-unknown}\n"
done

Note that this script will run much slower than the Python version.

terdon
  • 104,404
FedKad
  • 13,900
  • 1
    disagree that this is "pure" bash. even disregarding the dependencies on apt (which, sure, how else could you make this), grep and awk are not bash builtins. This is bash + coreutils – Themoonisacheese Jul 16 '25 at 14:32
  • Well, OK. The term pure was superfluous. – FedKad Jul 16 '25 at 15:51