Understanding package management in Linux

Delve into the heart of the package management system on Debian and Debian based Linux distributions. Understand what packages really are and how are they organized and distributed through packages repositories. Understand Apt ecosystem and perform essential package management tasks.

Understanding package management in Linux

Overview of the package management system

Packages

Softwares on Debian and Debian based Linux distributions are distributed through packages in the binary .deb format. To understand that format, lets have a look at the content of the tcpdump utilities .deb package:

$ apt download tcpdump
Get:1 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 tcpdump amd64 4.9.3-4ubuntu0.2 [369 kB]
Fetched 369 kB in 1s (484 kB/s)

$ ls
tcpdump_4.9.3-4ubuntu0.2_amd64.deb

$ ar x tcpdump_4.9.3-4ubuntu0.2_amd64.deb
$ rm tcpdump_4.9.3-4ubuntu0.2_amd64.deb
$ ls
control.tar.xz  data.tar.xz  debian-binary

Debian packages contain 3 main files:

  • debian-binary: a text file containing the version of the Debian package format
  • control.tar.xz: a compressed control.tar file containing metadata infos about the package (control file), hashsums of the package data files, optional maintainer scripts (postinst, preinst, postrm and prerm files), a list of the package supplied shared libraries and their dependencies (shlibs file), a list of the package configuration files (conffiles file) that need to be automatically handled by dpkg in the way described here. Here is a detailed explanation of the purpose of each file contained inside the control archive from the Debian Policy Manual: package control information files.
  • data.tar.xz: a compressed data.tar file containing package data (configuration files, binaries, man pages files...) inside folders relative to the target system root (/) directory.

Let's have a look at the content of the control.tar.xz and data.tar.xz files for the tcpdump package:

$ tar xfvJ control.tar.xz
./
./conffiles
./control
./md5sums
./postinst
./postrm

$ tar xfvJ data.tar.xz 
./
./etc/
./etc/apparmor.d/
./etc/apparmor.d/usr.sbin.tcpdump
./usr/
./usr/sbin/
./usr/sbin/tcpdump
./usr/share/
./usr/share/doc/
./usr/share/doc/tcpdump/
./usr/share/doc/tcpdump/NEWS.Debian.gz
./usr/share/doc/tcpdump/README.Debian
./usr/share/doc/tcpdump/README.md.gz
./usr/share/doc/tcpdump/changelog.Debian.gz
./usr/share/doc/tcpdump/copyright
./usr/share/doc/tcpdump/examples/
./usr/share/doc/tcpdump/examples/atime.awk
./usr/share/doc/tcpdump/examples/packetdat.awk
./usr/share/doc/tcpdump/examples/send-ack.awk
./usr/share/doc/tcpdump/examples/stime.awk
./usr/share/man/
./usr/share/man/man8/
./usr/share/man/man8/tcpdump.8.gz

Now let's have a look at the content of some of the control.tar.xz files:

$ cat conffiles 
/etc/apparmor.d/usr.sbin.tcpdump

$ cat control
Package: tcpdump
Version: 4.9.3-4ubuntu0.2
Architecture: amd64
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Installed-Size: 1088
Depends: libc6 (>= 2.14), libpcap0.8 (>= 1.5.1), libssl1.1 (>= 1.1.0), adduser
Suggests: apparmor (>= 2.3)
Breaks: apparmor-profiles-extra (<< 1.12~)
Replaces: apparmor-profiles-extra (<< 1.12~)
Section: net
Priority: optional
Multi-Arch: foreign
Homepage: https://www.tcpdump.org/
Description: command-line network traffic analyzer
 This program allows you to dump the traffic on a network. tcpdump
 is able to examine IPv4, ICMPv4, IPv6, ICMPv6, UDP, TCP, SNMP, AFS
 BGP, RIP, PIM, DVMRP, IGMP, SMB, OSPF, NFS and many other packet
 types.
 .
 It can be used to print out the headers of packets on a network
 interface, filter packets that match a certain expression. You can
 use this tool to track down network problems, to detect attacks
 or to monitor network activities.
Original-Maintainer: Romain Francoise <rfrancoise@debian.org>

$ cat md5sums 
f9f65bc725c89ea8ce57048342682cd1  usr/sbin/tcpdump
a061c78c03a68d8a54ef1dc7da2f9449  usr/share/doc/tcpdump/NEWS.Debian.gz
4cb3482753693a38d84271dcf8b74a25  usr/share/doc/tcpdump/README.Debian
7ccad1c5dd054c2f7ea93f6a7e1fab44  usr/share/doc/tcpdump/README.md.gz
86f3e3085841d8335d433614c1395b91  usr/share/doc/tcpdump/changelog.Debian.gz
0baa30c7e8a9d00c3102ddceb3643554  usr/share/doc/tcpdump/copyright
f62c99424d4bde287c842a1dc9d33cec  usr/share/doc/tcpdump/examples/atime.awk
2d2f4c9ef37a9ff6addd6f0b55acf1d2  usr/share/doc/tcpdump/examples/packetdat.awk
04eb6463bab3266110142040ae9fa63c  usr/share/doc/tcpdump/examples/send-ack.awk
a7753832551077724d0c8386ce106993  usr/share/doc/tcpdump/examples/stime.awk
2c7ff605f00017e7cd9e331ea42a3398  usr/share/man/man8/tcpdump.8.gz

$ cat postinst 
#!/bin/sh -e

if ! getent group tcpdump >/dev/null 2>&1; then
    addgroup --system --quiet tcpdump
fi
if ! getent passwd tcpdump >/dev/null 2>&1; then
    adduser --system --quiet --ingroup tcpdump          \
            --no-create-home --home /nonexistent        \
            tcpdump
fi

# Automatically added by dh_apparmor/2.13.3-7ubuntu5.2
if [ "$1" = "configure" ]; then
    APP_PROFILE="/etc/apparmor.d/usr.sbin.tcpdump"
    if [ -f "$APP_PROFILE" ]; then
        # Add the local/ include
        LOCAL_APP_PROFILE="/etc/apparmor.d/local/usr.sbin.tcpdump"

        test -e "$LOCAL_APP_PROFILE" || {
            mkdir -p `dirname "$LOCAL_APP_PROFILE"`
            install --mode 644 /dev/null "$LOCAL_APP_PROFILE"
        }

        # Reload the profile, including any abstraction updates
        if aa-enabled --quiet 2>/dev/null; then
            apparmor_parser -r -T -W "$APP_PROFILE" || true
        fi
    fi
fi
# End automatically added section

$ cat postrm 
#!/bin/sh -e

case "$1" in
    purge)
        userdel tcpdump >/dev/null 2>&1 || true
        groupdel tcpdump >/dev/null 2>&1 || true
        ;;
esac

# Automatically added by dh_apparmor/2.13.3-7ubuntu5.2
if [ "$1" = "purge" ] && ! [ -e "/etc/apparmor.d/usr.sbin.tcpdump" ] ; then
    rm -f "/etc/apparmor.d/disable/usr.sbin.tcpdump" || true
    rm -f "/etc/apparmor.d/force-complain/usr.sbin.tcpdump" || true
    rm -f "/etc/apparmor.d/local/usr.sbin.tcpdump" || true
    rm -f /var/cache/apparmor/*/"usr.sbin.tcpdump" || true
    rmdir /etc/apparmor.d/disable 2>/dev/null || true
    rmdir /etc/apparmor.d/local   2>/dev/null || true
    rmdir /etc/apparmor.d         2>/dev/null || true
fi
# End automatically added section

Now that we know which files and type of files a Debian package is made of, let's see how we can create a .deb package. For that, we need to organize our package files as follows:

packagename_version_arch
├── DEBIAN
├── etc
├── usr
└── ...

Inside the DEBIAN directory, we put all the package control information files.

Then, at the same level as the DEBIAN directory, we create the package data files. The data files should be organized as a miniature filesystem relative to the target system root (/) directory and have the ownerships and permissions they should have on the systems where they are installed. Which means that the same uid/username and gid/groupname should be present on the built and the target system. Have a look at the Debian Policy Manual package creation section for more.

Once the package directory tree is ready, we use the dpkg --build <packagedir> to create the .deb package.

Here is an example with the previously extracted tcpdump package files. We want to recreate the tcpdump_4.9.3-4ubuntu0.2_amd64.deb package from them. For that, we create a tcpdump_4.9.3-4ubuntu0.2_amd64 folder, with the following directory tree:

$ tree tcpdump_4.9.3-4ubuntu0.2_amd64
tcpdump_4.9.3-4ubuntu0.2_amd64
├── DEBIAN
│   ├── conffiles
│   ├── control
│   ├── md5sums
│   ├── postinst
│   └── postrm
├── etc
│   └── apparmor.d
│       └── usr.sbin.tcpdump
└── usr
    ├── sbin
    │   └── tcpdump
    └── share
        ├── doc
        │   └── tcpdump
        │       ├── NEWS.Debian.gz
        │       ├── README.Debian
        │       ├── README.md.gz
        │       ├── changelog.Debian.gz
        │       ├── copyright
        │       └── examples
        │           ├── atime.awk
        │           ├── packetdat.awk
        │           ├── send-ack.awk
        │           └── stime.awk
        └── man
            └── man8
                └── tcpdump.8.gz

Then, we use dpkg to create the package as follows:

$ dpkg --build tcpdump_4.9.3-4ubuntu0.2_amd64
dpkg-deb: building package 'tcpdump' in 'tcpdump_4.9.3-4ubuntu0.2_amd64.deb'.

$ file tcpdump_4.9.3-4ubuntu0.2_amd64.deb
tcpdump_4.9.3-4ubuntu0.2_amd64.deb: Debian binary package (format 2.0), with control.tar.xz, data compression xz

Packages repositories

Linux packages repositories are simply places from where packages files are served. Those places could be for instance local filesystems, http/https or ftp services. Here is a common directory tree we found inside public Debian and Debian based Linux distributions repositories.

debrepo/
├── dists
│   └── suite
│       ├── Contents-arch.gz
│       ├── InRelease
│       ├── Release
│       ├── Release.gpg
│       └── component
│           ├── binary-arch
│           │   ├── Packages.gz
│           │   ├── Packages.xz
│           │   └── Release
│           ├── i18n
│           │   ├── Index
│           │   ├── Translation-lang
│           │   ├── Translation-lang.gz
│           │   └── Translation-lang.xz
│           └── source
│               ├── Release -> ../binary-arch/Release
│               ├── Sources.gz
│               └── Sources.xz
└── pool
    └── component
        └── m
            └── mypackage
                ├── mypackage_1.0.debian.tar.xz
                ├── mypackage_1.0.dsc
                ├── mypackage_1.0.orig.tar.xz
                └── mypackage_1.0_arch.deb

At the packages repository toplevel, we found the dists and pool directories.

The dists directory contains Translation files for packages descriptions, the Contents files (a mapping between packages and files they own) and the Release, Packages and Sources files).

The pool directory contains binary packages (.deb) and packages sources files (compressed .orig.tar), sources differences and patches files (compressed .debian.tar), the packages sources control file (.dsc) and potentially other kind of files we are not necessarily interrested in.

Suite, codename, component and section

The files inside the dists and pool directories are repectively part of the suite and component subdirectories.

The suite most of the time corresponds to the Linux distribution codename plus an optional suffix. In our above example, the suite directory could be focal, focal-updates, etc. Have a look at ubuntu repository dists content for more examples.

The component names correspond to packages areas as defined by the Linux distributions. For instance, in Debian, there are 3 packages areas (main, contrib, non-free). Have a look at Debian packages repository components for infos about the purpose of each packages area.

In Ubuntu, there are 4 components or packages areas (main, universe, restricted, multiverse). Have a look at Ubuntu packages repository components (summary) or Ubuntu packages repository components (detailed) for infos about the purpose of each packages area.

Packages are further grouped into sections inside each area to simplify they handling. The section corresponds to the category of the package. The list of the different packages sections can be found at Debian archive sections.

Contents files

Contents* files inside packages repositories contain a mapping between packages and files they own. Here is an extract from Ubuntu packages repository:

bin/afio						    multiverse/utils/afio
bin/archdetect						    utils/archdetect-deb
bin/ash							    universe/shells/ash
bin/autopartition					    admin/ubiquity
bin/autopartition-crypto				    admin/ubiquity
bin/autopartition-loop					    admin/ubiquity
bin/autopartition-lvm					    admin/ubiquity
bin/bash						    shells/bash
(...)
boot/vmlinuz-4.15.0-20-generic				    kernel/linux-image-4.15.0-20-generic,kernel/linux-image-unsigned-4.15.0-20-generic
boot/vmlinuz-4.15.0-20-lowlatency			    kernel/linux-image-4.15.0-20-lowlatency,kernel/linux-image-unsigned-4.15.0-20-lowlatency
boot/xen-4.9-amd64.efi					    universe/kernel/xen-hypervisor-4.9-amd64
boot/xen-4.9-amd64.gz					    universe/kernel/xen-hypervisor-4.9-amd64
etc/3270/ibm_hosts					    universe/net/3270-common
etc/Aria						    universe/libs/libaria2
etc/Crack/dictgrps.conf					    universe/admin/crack-common
etc/Crack/dictrun.conf					    universe/admin/crack-common
(...)

Left we have the root (/) relative path to the package files once it is installed on a system. At the right, the name(s) of the package(s) owning the file in the form component/section/package_name for packages outside the main component or section/package_name for packages inside the main component.

Packages files

Here is an extract of Packages* files content from a Debian based Linux distribution repository:

Package: bash
Version: 4.3-11+deb8u1
Essential: yes
Installed-Size: 5010
Maintainer: Matthias Klose <doko@debian.org>
Architecture: amd64
Replaces: bash-completion (<< 20060301-0), bash-doc (<= 2.05-1)
Depends: base-files (>= 2.1.12), debianutils (>= 2.15)
Pre-Depends: dash (>= 0.5.5.1-2.2), libc6 (>= 2.15), libncurses5 (>= 5.5-5~), libtinfo5
Recommends: bash-completion (>= 20060301-0)
Suggests: bash-doc
Conflicts: bash-completion (<< 20060301-0)
Description: GNU Bourne Again SHell
Multi-Arch: foreign
Homepage: http://tiswww.case.edu/php/chet/bash/bashtop.html
Description-md5: 3522aa7b4374048d6450e348a5bb45d9
Tag: implemented-in::c, interface::shell, role::program, scope::utility,
 suite::gnu, uitoolkit::ncurses
Section: shells
Priority: required
Filename: pool/main/b/bash/bash_4.3-11+deb8u1_amd64.deb
Size: 1171862
MD5sum: d45364ae9573bf742625fe504f764ac4
SHA1: a61d501276ecc394f7d5ccabd649b905f3d5b551
SHA256: fbba12207fd2469478b95913b1e59d8b9952cc77685693133b13f06f14292590

The Packages* files contain infos about each package present inside the corresponding package area (component folder) for the corresponding package binary architecture (binary-arch folder). It contains multiple blocks of text like the one shown above separeted by empty lines. The Debian policy binary package control files section gives useful infos about the different fields inside that file (what are they used for, are they mandatory, etc).

Translation files

The Tanslation* files inside the i18n folder contain tanslations for packages descriptions. Here is an extract translation file in en_CA language for the bash package:

Package: bash
Description-md5: 3522aa7b4374048d6450e348a5bb45d9
Description-en_CA: GNU Bourne Again SHell
 Bash is an sh-compatible command language interpreter that executes
 commands read from the standard input or from a file.  Bash also
 incorporates useful features from the Korn and C shells (ksh and csh).
 .
 Bash is ultimately intended to be a conformant implementation of the IEEE
 POSIX Shell and Tools specification (IEEE Working Group 1003.2).
 .
 The Programmable Completion Code, by Ian Macdonald, is now found in the
 bash-completion package.

For a given package, the Description-md5 field has the same value inside the transation and package files. That's how the link between the package and its description translations is made.

Sources files

Here is an extract of Sources* files content from a Debian based Linux distribution repository:

Package: mysql-connector-python
Binary: python-mysql.connector, python3-mysql.connector
Version: 1.2.3-2
Maintainer: Sandro Tosi <morph@debian.org>
Uploaders: Debian Python Modules Team <python-modules-team@lists.alioth.debian.org>, Brian May <bam@debian.org>
Build-Depends: debhelper (>= 7.0.50~), python-all, dh-python, python3-all, mysql-server
Architecture: all
Standards-Version: 3.9.5
Format: 3.0 (quilt)
Files:
 1f6375f58609695534749a32aa3dd6af 1633 mysql-connector-python_1.2.3-2.dsc
 63dc50988498fbc520f69a7278b46a2d 285849 mysql-connector-python_1.2.3.orig.tar.gz
 09acacbbddf3d838ce1e6c99b7c705fe 4028 mysql-connector-python_1.2.3-2.debian.tar.xz
Vcs-Browser: http://anonscm.debian.org/viewvc/python-modules/packages/mysql-connector-python/trunk/
Vcs-Svn: svn://anonscm.debian.org/python-modules/packages/mysql-connector-python/trunk/
Checksums-Sha1:
 b8766d1115f6a24614a798b44e61fc65910cd369 1633 mysql-connector-python_1.2.3-2.dsc
 51ffded1503a1c97aeb6b739beb6551e452a2b05 285849 mysql-connector-python_1.2.3.orig.tar.gz
 c3cf780ac99bfcba0e31dfe29e28a62f6c54597d 4028 mysql-connector-python_1.2.3-2.debian.tar.xz
Checksums-Sha256:
 a66976704d095ce24fa9758113f9114559290da9c284de8f644567c2930f63f9 1633 mysql-connector-python_1.2.3-2.dsc
 03b4ba1c2d4ede2817137b487b3d2e1e38e6ed9423fe91bf13db2fe739a33350 285849 mysql-connector-python_1.2.3.orig.tar.gz
 ce5f8140d5dc3530e00c918b3aa34f5128d6f39358ead3e7931fbd30981d40c4 4028 mysql-connector-python_1.2.3-2.debian.tar.xz
Homepage: http://dev.mysql.com/doc/connector-python/en/index.html
Package-List: 
 python-mysql.connector deb python optional arch=all
 python3-mysql.connector deb python optional arch=all
Directory: pool/main/m/mysql-connector-python
Priority: source
Section: python

The Sources* files contain infos about each package sources present inside the corresponding package area (component folder). It contains multiple blocks of text like the one shown above separeted by empty lines. The Debian policy source control files section gives useful infos about the different fields inside that file (what are they used for, are they mandatory, etc).

Release and InRelease files

Release files inside the following directories:

  • <distribution_name>/dists/<distribution_suite>/<distribution_component>/binary-<arch>
  • <distribution_name>/dists/<distribution_suite>/<distribution_component>/source

are legacy files that repositories clients must not use anymore.

The Release or InRelease files inside the following directory are the entrypoint for verifying repository files and packages integrity:

  • <distribution_name>/dists/<distribution_suite>
    • Example: ubuntu/dists/focal-updates

They contain checksums for each file inside the repository and are themselves digitally signed with GPG private keys. The InRelease file includes the GPG signature whereas the Release file has a detached signature contained inside the Release.gpg file.

Public keys required to verify the signature of the Release or InRelease file come preinstalled inside the Linux distribution for Apt, in order to make sure packages from the official distribution repositories can be verified before installation. The keys are provided by ubuntu-keyring and debian-archive-keyring packages respectively on Ubuntu and Debian.

Here are some extracts of the InRelease and Release files:

  • InRelease file:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Origin: Ubuntu
Label: Ubuntu
Suite: focal-updates
Version: 20.04
Codename: focal
Date: Sun, 26 Nov 2023 17:11:33 UTC
Architectures: amd64 arm64 armhf i386 ppc64el riscv64 s390x
Components: main restricted universe multiverse
Description: Ubuntu Focal Updates
MD5Sum:
 14e7942e7e0deec60e086808aab9c30b       4206401750 Contents-amd64
 62b3586069399b1af97cfe0494a1f1d5        231951436 Contents-amd64.gz
 (...)
 644a10229e397ef605b1fe159258db18         16502614 main/binary-amd64/Packages
 226f94e8d8f625fbb7c4eb92ab0d3ac7          3712253 main/binary-amd64/Packages.gz
 693c877779a4d65ed62c2369366a8396          2981456 main/binary-amd64/Packages.xz
 10aef129feae6b2d9c46070bc0bd64c5              103 main/binary-amd64/Release
 (...)
SHA256:
 ecf6e10975baef4271edac72231e34b46cd9348b0eb55083c962077dd5fbfafc          3768066 main/debian-installer/binary-amd64/Packages
 a1757525d4c2db2b932f931d6a87aba7e5f0bd822d39a1e0240a3b845d5b1ad2           925595 main/debian-installer/binary-amd64/Packages.gz
 (...)
 6dc5a7b389c7f9fa14179db8160ed3f9e1eb237d358736794ee11f5597b1bf7b              109 multiverse/binary-armhf/Release
 582d06aca9ae24da46df709b11382f5b0c99da79756f8589a4bd73baabb2970d            36645 multiverse/binary-i386/Packages
 eae8e954a0b0d7e0ec30fba4606eea8e16f03d5973a1aa85c97cb3aa0905575c             9586 multiverse/binary-i386/Packages.gz
 7cb62bd5f13aa1f6bbce339e23c17ddd62ec41b9fc4816cef153e63b675e8517             8440 multiverse/binary-i386/Packages.xz
 345f45aeef51f20cce08f7791374e0c42c9018f6e6417a3dd1203d871bd6ac7c              108 multiverse/binary-i386/Release
  eb79da10c5730ec16e5ee638898c3bccf2a6cbe9362722064e1beaddb367da1b          2304515 universe/i18n/Translation-en
 bb8a01c5e9b8ad79cf0f90278e242f38688475f1f73bec35ad9dc58825579f04           376317 universe/i18n/Translation-en.gz
 9e916c7a23e3cd2f0f6cf708b3aabc029c4c8a07368d72feaf0122192bae446e           270496 universe/i18n/Translation-en.xz
 c1f8f711c2c8f1de06358bbf89960229b723886d8d8c876897c55c68b1921a97              108 universe/source/Release
 a5664889a9c9fd6f190ca3ae214587f28342c2290ee43d83e1d8991bc0d285c7          1607958 universe/source/Sources
 f8efdbea8bf4b609af4131660e49a6ddadaa2e1c4a35aede6f1deee46d900316           441034 universe/source/Sources.gz
 b29f3085fd8815bf5ab7843ca88d2f19a3e4a897c8504a87ed6e4eb0633e071d           353376 universe/source/Sources.xz
Acquire-By-Hash: yes
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEeQvHJ3dnIZxCyG+TO0/mrMCyHzIFAmVjfL8ACgkQO0/mrMCy
HzKVXhAAslKUxHJeT6XUbdOEQCYBod66qVoAcO2n+bin0EEmc9lRG0JNHapPa9BN
(...)
DUDYRnTb1voA73iPB+2Q/vQp1pn4uE5DfwiZeb9I0PPdfrYWBiRHK/M9RRSaAeRs
IsQt9aYDGwKoL6iuQ2VgmdDTuXCmWc9LXIC/hsjW35tvpi2yQodoDI7ItY7iPtce
SALVNtRoyAD9nhi8+XJ6IDTBwus9DQoiUnm+Ug==
=qAc6
-----END PGP SIGNATURE-----
  • Release file
Origin: Ubuntu
Label: Ubuntu
Suite: focal-updates
Version: 20.04
Codename: focal
Date: Sun, 26 Nov 2023 17:11:33 UTC
Architectures: amd64 arm64 armhf i386 ppc64el riscv64 s390x
Components: main restricted universe multiverse
Description: Ubuntu Focal Updates
MD5Sum:
 14e7942e7e0deec60e086808aab9c30b       4206401750 Contents-amd64
 62b3586069399b1af97cfe0494a1f1d5        231951436 Contents-amd64.gz
 (...)
 644a10229e397ef605b1fe159258db18         16502614 main/binary-amd64/Packages
 226f94e8d8f625fbb7c4eb92ab0d3ac7          3712253 main/binary-amd64/Packages.gz
 693c877779a4d65ed62c2369366a8396          2981456 main/binary-amd64/Packages.xz
 10aef129feae6b2d9c46070bc0bd64c5              103 main/binary-amd64/Release
 (...)
SHA256:
 ecf6e10975baef4271edac72231e34b46cd9348b0eb55083c962077dd5fbfafc          3768066 main/debian-installer/binary-amd64/Packages
 a1757525d4c2db2b932f931d6a87aba7e5f0bd822d39a1e0240a3b845d5b1ad2           925595 main/debian-installer/binary-amd64/Packages.gz
 (...)
 6dc5a7b389c7f9fa14179db8160ed3f9e1eb237d358736794ee11f5597b1bf7b              109 multiverse/binary-armhf/Release
 582d06aca9ae24da46df709b11382f5b0c99da79756f8589a4bd73baabb2970d            36645 multiverse/binary-i386/Packages
 eae8e954a0b0d7e0ec30fba4606eea8e16f03d5973a1aa85c97cb3aa0905575c             9586 multiverse/binary-i386/Packages.gz
 7cb62bd5f13aa1f6bbce339e23c17ddd62ec41b9fc4816cef153e63b675e8517             8440 multiverse/binary-i386/Packages.xz
 345f45aeef51f20cce08f7791374e0c42c9018f6e6417a3dd1203d871bd6ac7c              108 multiverse/binary-i386/Release
 eb79da10c5730ec16e5ee638898c3bccf2a6cbe9362722064e1beaddb367da1b          2304515 universe/i18n/Translation-en
 bb8a01c5e9b8ad79cf0f90278e242f38688475f1f73bec35ad9dc58825579f04           376317 universe/i18n/Translation-en.gz
 9e916c7a23e3cd2f0f6cf708b3aabc029c4c8a07368d72feaf0122192bae446e           270496 universe/i18n/Translation-en.xz
 c1f8f711c2c8f1de06358bbf89960229b723886d8d8c876897c55c68b1921a97              108 universe/source/Release
 a5664889a9c9fd6f190ca3ae214587f28342c2290ee43d83e1d8991bc0d285c7          1607958 universe/source/Sources
 f8efdbea8bf4b609af4131660e49a6ddadaa2e1c4a35aede6f1deee46d900316           441034 universe/source/Sources.gz
 b29f3085fd8815bf5ab7843ca88d2f19a3e4a897c8504a87ed6e4eb0633e071d           353376 universe/source/Sources.xz
Acquire-By-Hash: yes

The Acquire-By-Hash: yes line indicates that indexes files (Packages*, Contents*, Translation*, sources*...) can be acquired via a URI constructed from their hashsums instead of using the well-known stable filename.

  • For instance, to get:
http://repo/ubuntu/dists/focal-updates/multiverse/binary-i386/Packages.gz
  • we could use:
http://repo/ubuntu/dists/focal-updates/multiverse/binary-i386/by-hash/SHA256/7cb62bd5f13aa1f6bbce339e23c17ddd62ec41b9fc4816cef153e63b675e8517

That way of downloading indexes files can be used to avoid hashsum mismatches. Have a look at By-Hash inside man 5 sources.list for Apt configuration.

What happens when Apt retrieves packages from repositories ?

In order to download and install packages, here is a simple overview of how Apt will proceeds:

  • Download the Release or InRelease file from the package repository and verify the signature
  • Download the compressed Packages index file
  • Verify the integrity of Packages index file using the hashsum provided inside the Release or InRelease file
  • Search for the package inside Packages index file and get one of its computed hashsums (md5, sha256...)
  • Download the package (.deb file)
  • Verify the package integrity using its previously retrieved hashsum
  • Install the package using Dpkg if integrity check succeeds

Package management tools

Apt stands for Advance Packaging Tool. Its a suite of command line interfaces used for package management on Debian and Debian based Linux distributions. Actually, behind the scene, Apt makes use of Dpkg (the Debian package manager) for installing, configuring and removing packages.

In addition to providing user-friendly frontends for Dpkg, Apt comes with many more features. Here are some of them listed below:

  • search, download, install packages from remote repositories
  • automated packages dependencies resolution and installation
  • packages upgrade
  • (...)

Here is a list of some of the tools inside the Apt suite of tools:

  • apt
  • apt-get
  • apt-cache
  • apt-key
  • apt-config
  • (...)

Apt configuration files and priorities

All the tools inside the Apt suite of tools read configuration items from the following locations:

  • /etc/apt/apt.conf: the main configuration file.
  • /etc/apt/apt.conf.d/*: the drop-in configuration files. Those are alphanumeric named files with either no or the .conf extension. The file names can also contain hyphen (-), underscore (_) and period (.). The files here are read in ascending alphanumeric order (10periodic read before 20auto-upgrades) and items inside the lately read files take precedence over those inside the primarily read ones. Files ending with .disabled, ~, .bak or .dpkg-[a-z]+ are ignored.

Configuration items inside the main configuration file take precedence over those inside the drop-in configuration files.

Configuration items can also be specified directly on the command line by using the -o flag. This takes precedence over items specified inside the main and drop-in configuration files.

Apt configuration syntax

Here is the syntax to use inside Apt configuration files:

First form : one line

# First form
GROUP::SUBGROUP::Option-name "value";

# or this for configuration items without subgroup
GROUP::Option-name "value";

Second form : curly braced

// Second form
GROUP {
  SUBGROUP {
    Option-name-1 "Option-value-1";
    Option-name-2 "Option-value-2";
    (...)
  };
};

# or

GROUP::SUBGROUP {
    Option-name-1 "Option-value-1";
    Option-name-2 "Option-value-2";
    (...)
  };
};

/* 
for configuration items 
without subgroup
*/
GROUP {
    Option-name-1 "Option-value-1";
    Option-name-2 "Option-value-2";
    (...)
  };
};
  • // and # are used for single line comments
  • /**/ is used for multiline comments
  • quotation marks ("") and trailing semicolon (;) are required
  • configuration items are case insensitive

As seen previously, Apt configuration items are made of a GROUP, sometimes a SUBGROUP (not for all configuration items), an option name and finally an option value.

Configuration items are specified using either the one line form with double colon notation (::) or the curly braced form with either curly braces ({}) only or a mix of curly braces ({}) and double colon (::).

While configuration items using the one line form can't be multilined, those declared with the curly braced form could be either single lined or multilined.

Configuration items with list of values

Some of the Apt configuration items require a list of values. This is the case for instance for the Acquire::CompressionTypes::Order configuration item, which sets the order in which Apt will try to download packages depending on their compression types.

When updating a list configuration item, values specified won't override the existing list, but will be appended to the begining of the list. Here is an example:

/* 
One line form
Only work with a list of one item
Used to append the item to the begining
of the existing list. Done with the
double colon (::) at the end of the 
configuration item
*/
Acquire::CompressionTypes::Order:: "gz";

/*
Curly braced form
This will make xz and gz the preferred 
compression types over the others... 
The other compression types are implicitely
added to the list
*/
Acquire::CompressionTypes::Order { "xz"; "gz"; }; 

Apt configuration examples

Here are example configuration items.

One line syntax
# GROUP=APT ; SUBGROUP=Get
APT::Get::Assume-Yes "true";
APT::Get::Fix-Broken "true";

# Configuration item without subgroup
# GROUP=Acquire ; no SUBGROUP
Acquire::AllowInsecureRepositories "0";
Acquire::AllowWeakRepositories "0";
Curly braced syntax
# GROUP=APT ; SUBGROUP=Get
APT {
  Get {
    Assume-Yes "true";
    Fix-Broken "true";
  };
};

# or

APT::Get { 
  Assume-Yes "true";
  Fix-Broken "true";
}

# Configuration items without subgroup
# GROUP=Acquire ; no SUBGROUP
Acquire { 
  AllowInsecureRepositories "0";
  Acquire::AllowWeakRepositories "0";
}
Command line syntax
$ any_apt_cli_tool \
  -o APT::Get::Assume-Yes=true \
  -o APT::Get::Fix-Broken=true \
  -o AllowInsecureRepositories=false \
  -o Acquire::AllowWeakRepositories=false

Apt configuration groups

Apt configuration items are organized into funtional groups. For instance, in this configuration item:

  • APT::Get::Assume-Yes "true";

APT is the functional group. Inside the functional group, we will either :

  • set options inside a subgroup (or subsection). This is the case in the previous configuration item, where Get is the subgroup (or subsection) and Assume-Yes the option.
  • set options directly in the group. APT::Architecture "amd64"; for instance, where APT is the group and Architecture the option.

A good startup point for finding Apt configuration groups, what are they for, and the options they provide is the Apt configuration manual. To access the manual locally on any Debian based Linux distribution, use the man 5 apt.conf command. To access the manual online, follow this link: apt.conf.5.html.

The APT group

The APT group controls general APT behavior as well as holding the options for all of the tools inside the Apt suite of tools.

The Get and Cache subgroups of options respectively control the apt-get and apt-cache tools. Available options for those subgroups can be found directly inside the tools manual pages, at the options section. Here is the options for apt-get and the options for apt-cache. At the end of each option description, the Apt configration item to use is shown.

The Periodic and Archives subgroups of options control the behavior of Apt periodic updates. They can be used to configure automated package upgrades on the system. The available options for those subgroups are described at the top of the /usr/lib/apt/apt.systemd.daily script.

Automated package security upgrades

The APT::Periodic::Unattended-Upgrade configuration item can be used to enable/disable automated package security upgrades through the unattended-upgrades script. In many Ubuntu versions, the upgrade seems to be activated by default through the /etc/apt/apt.conf.d/20auto-upgrades configuration file.

The unattended-upgrades script behavior can be configured through the /etc/apt/apt.conf.d/50unattended-upgrades configuration file. Configuration options for the unattended-upgrades script are put inside the Unattended-Upgrade group. Here are some example configuration items for tuning the unattended-upgrades script behavior:

  • Unattended-Upgrade::Allowed-Origins: a list that defines the repository components from which newly available packages will be automatically installed. Configured by default to only include security fixes.
  • Unattended-Upgrade::Automatic-Reboot: weather to enable automatic reboot for upgrades requiring it
  • Unattended-Upgrade::Automatic-Reboot-Time: time on which automatic reboot will be performed when necessary
  • (...) for the list of all available configuration items and what they do, have a look at the /etc/apt/apt.conf.d/50unattended-upgrades configuration file

In recent Ubuntu versions, the unatteded-upgrades script periodic execution is controlled by 2 systemd services and their associated systemd timers:

  • apt-daily.service: download package information from all configured sources. Useful to get latest package informations before performing upgrades
  • apt-daily.timer: systemd timer that schedule execution of the apt-daily.service
  • apt-daily-upgrade.service: performs package upgrades using the unattended-upgrades script
  • apt-daily-upgrade.timer: systemd timer that schedule execution of the apt-daily-upgrade.service

For seeing in advance what the unattended-upgrades script will do on next execution without really performing any upgrades, we can call it with the --dry-run flag as follows:

$ unattended-upgrades --dry-run

The ACQUIRE group

The ACQUIRE group controls the behavior of Apt when downloading packages. Here is a list of things we can configure through that group:

  • IP protocols: ipv4, ipv6 ...
  • Proxies: http, https and ftp
  • Package and repository security:
    • enable/disable time related checks on packages Release file
    • allow/disallow operations from repositories considered weak or insecure
  • Optimization and failure handling:
    • preferred compression types
    • outgoing connections parallelization modes
    • number of retries after failure
    • package indexes download modes
  • (...)
Example: setting up http proxy
Acquire::http {
  // Use this proxy when acquiring packages using http
  // Here is the format for proxy value : 
  // scheme://[[user][:pass]@]host[:port]
  Proxy "http://my.proxy:3128"; 
  
  // Do not use proxy for package.repo.local host/domain name
  Proxy::package.repo.local "DIRECT";
  
  // Auto detect proxy settings using a script.
  // The script should return the proxy settings in the
  // scheme://[[user][:pass]@]host[:port] format
  Proxy-Auto-Detect "/usr/local/bin/apt-http-proxy-auto-detect";
  
  // Tell the proxy to not use its cached
  // response under any circumstances 
  No-Cache "true";
  
  // Maximum allowed age in seconds of an
  // index file in the cache of the proxy
  Max-Age "3600";
  
  // Tell the proxy to not store requested
  // archive files in its cache. This prevents 
  // polluting the cache with .deb files
  No-Store "true";
  
  // Connection and data timeout
  Timeout "10";
  
  // Bandwith limit in kilobytes per second.
  // Default to 0 = unlimited
  Dl-Limit "42";
  
  //
  AllowRedirect "false";
  
  // User agent for the http download method
  // (before reaching the proxy)
  User-Agent "My APT-HTTP"
}

The DIR group

The DIR group can be used to configure the following :

  • location of binaries used by Apt. We use Dir::Bin for that :
    • Dir::Bin::Methods: path to the directory containing handler binaries for the different Apt methods (http, https, ftp, ssh, cdrom, file, copy...)
    • Dir::Bin::<binary_name>: other binaries specific paths. For instance Dir::Bin::dpkg to configure the path to the dpkg binary that will be used by Apt
  • the root directory to which all the other configured paths (binaries, local and state infos, config dirs...) are relative. Dir::RootDir can be used to set it. Default to /.
  • directories containing local cache and state information:
    • Dir::State: default path to the directory containing local state information. That path is relative to Dir::RootDir. Default to var/lib/apt
    • Dir:State::lists: path to the directory containing downloaded files from the configured package sources/repositories, after running the apt[-get] update command. The downloaded files include: Release or InRelease files, the Contents files, the Translations and Packages files. The path is relative to Dir::State unless started with / or ./. Default to lists/. The apt-cache show <package-name> command can be used to get infos about a package from the downloaded package lists files present inside that directory.
    • Dir::State::status: path to the Dpkg status file containing infos about installed packages. That path is relative to Dir::State unless started with / or ./. Default to /var/lib/dpkg/status.
  • location of Apt configuration files and directories :
    • Dir::Etc: Dir::RootDir relative path to the directory containing Apt configuration files. Apt tools will read Apt configuration settings from files inside that directory. Default to etc/apt
    • Dir::Etc::main: the default Apt configuration file inside Dir::Etc. Default to apt.conf. Changing this will have no effect. The only way to change the path of the default Apt configuration file is to set it through the APT_CONFIG environment variable.
    • Dir::Parts: directory containing fragment Apt configuration files inside Dir::Etc. Default to apt.conf.d.
    • Dir::Etc::sourcelist: packages sources configuration file inside Dir::Etc. Default to sources.list
    • Dir::Etc::sourceparts: directory containing packages sources fragment configuration files inside Dir::Etc. Default to sources.list.d
    • The Dir::Etc can also be used to set default and fragment configurations file and directory for the following:
      • netrc and netrcparts: repectively configure paths to login default configuration file and fragment configurations directory for APT sources and proxies inside Dir::Etc. Repectively default to auth.conf and auth.conf.d. See apt_auth.conf to know how to use Apt authentication configuration files.
      • preferences and preferencesparts: repectively configure paths to preferences control file for APT inside Dir::Etc. Repectively default to preferences and preferences.d. See apt_preferences to control which versions of packages will be selected for installation by Apt.
  • a list of patterns for configuration files inside the Apt fragment configurations directory (/etc/apt/apt.conf.d) that should be ignored. Dir::Ignore-Files-Silently can be used to set it. Use apt-config dump | grep -i Ignore-Files-Silently to get the current value of that list.

Binary specific configuration

It is possible to set configurations only for specific Apt binaries by prefixing the configuration items with binary::<binary_name>::.

For instance, if we want to set the APT::Get::Assume-Yes: "true"; only for the apt binary we can use binary::apt::APT::Get::Assume-Yes: "true"; inside Apt configuration files. The apt-get and other tools will not be affected by that.

Reading active Apt configuration settings

Configuration parameters that will be taken into account by all of the tools inside the Apt suite of tools can be read using the apt-config utility as follows:

# List all active configuration settings
$ apt-config dump

# Only show active configuration settings
# related to the Dir group
apt-config dump | grep -i dir::

Configure package sources

Packages sources are used to tell Apt where to get packages from. Packages sources can be configured using the following files:

  • /etc/apt/sources.list: the main configuration file. By default, contains the declaration of the Linux distributions official packages repositories
  • /etc/apt/sources.list.d/*: the drop-in packages sources configuration files. Those files can be used to add additional sources.list entries and should have .list or .sources extensions depending on the configuration format used (.list for the one-line-style format and .sources for the deb822-style format. The files names may only contain alphanumeric characters, underscore (_), hyphen (-) and period (.).

Preferred sources must be listed first in case a single version is available from more than one source.

Packages sources configuration syntax

One line style
deb [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]
deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]
  • The traditional format supported by all Apt versions. Used in configuration files with .list extension
  • Values for multivalue options are separated by comma (,)
  • += and -= can be used as separators for multivalue options to modify the default value (instead of replacing it) by repectively adding or removing given values
  • # character can be used for comments
Deb822 style
Types: deb or deb-src (or both)
URIs: uri
Suites: suite
Components: [component1] [component2] [...]
option1: value1
option2: value2
  • The new format supported by Apt since version 1.1. Used in configuration files with .sources extension.
  • The Apt team intend to gradually make deb822-style the default format as it it easier to use for humans and machines
  • Values for multivalue fields are separated by whitespaces (spaces, tabs, newlines). Multivalue options fields also have <fieldname>-Add and <fieldname>-Remove fields that can be used to modify the default value (instead of replacing it) by repectively adding or removing given values
  • Multiple entries like the one shown above are separated by an empty line. The Enabled field on any entry can be used to enable or disable that entry
  • # character can be used for comments
Packages sources configuration examples
# One-line-style
$ cat /etc/apt/sources.list.d/docker.list
deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu focal stable

# Deb822-style
$ cat /etc/apt/sources.list.d/docker.sources
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: focal
Components: stable
arch: amd64
signed-by: /etc/apt/keyrings/docker.gpg

For more examples, have a look at sources.list.5.examples

Debconf

Debconf is a system / protocol that can be used by Debian package maintainers to ease their packages configuration. It provides users a way to configure packages before (preconfiguration), during or after installation (reconfiguration) by answering questions (coming from templates : /var/cache/debconf/templates.dat) about configuration settings through different frontend interfaces (dialog box, text editor...). Once provided, configuration settings are stored inside debconf configuration database (default : /var/cache/debconf/config.dat) for use during package configuration steps. For more about debconf configuration files, have a look at debconf.conf.5.html

Packages using debconf include, in addition to traditional maintainer scripts (postinst, preinst, postrm and prerm files), a config script and templates file inside their control.tar.xz archive. The config script will be run to get configuration settings directly from debconf database if already set or from users and then store them into debconf configuration database. The templates file contains the list of configuration settings questions that may be asked to users, and their descriptions. The questions have priorities (low, medium, high or critical) and users can decide, when configuring packages through debconf, to answer only questions with a specific priority a least. For more about what is required to make packages use debconf and the debconf protocol itself, have a look at debconf-devel.7.html

The dpkg-preconfigure and dpkg-reconfigure command line utilities can be used to respectively configure packages using debconf before and after installation. When installing packages using Apt utilities (apt, apt-get...), those using debconf are automatically preconfigured through dpkg-preconfigure thanks to the Apt configuration settings present inside the /etc/apt/apt.conf.d/70debconf file. That preconfiguration, when run for the first time on a package, will sometimes show users a dialog box (default debconf interface) asking them to answer some configuration questions or show nothing because the package doesn't use debconf or because there is no questions to ask.

Essential package management tasks

Search for packages

$ apt search <package_name_or_regex>

# Example:

$ apt search ^bash

Get infos about packages

  • List all packages
$ apt list
  • List installed packages
$ apt list --installed
  • List upgradable packages
$ apt list --upgradable
  • To get infos about a specific package from the packages index file (/var/lib/apt/lists/*_Packages), use:
$ apt show <package_name_or_regex>

# Example:

$ apt show bash
Package: bash
Version: 5.0-6ubuntu1.2
Priority: required
Essential: yes
Section: shells
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Matthias Klose <doko@debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 1700 kB
Pre-Depends: libc6 (>= 2.15), libtinfo6 (>= 6)
Depends: base-files (>= 2.1.12), debianutils (>= 2.15)
Recommends: bash-completion (>= 20060301-0)
Suggests: bash-doc
Conflicts: bash-completion (<< 20060301-0)
Replaces: bash-completion (<< 20060301-0), bash-doc (<= 2.05-1)
Homepage: http://tiswww.case.edu/php/chet/bash/bashtop.html
Task: minimal
Download-Size: 639 kB
APT-Manual-Installed: yes
APT-Sources: http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages
Description: GNU Bourne Again SHell
 Bash is an sh-compatible command language interpreter that executes
 commands read from the standard input or from a file.  Bash also
 incorporates useful features from the Korn and C shells (ksh and csh).
 .
 Bash is ultimately intended to be a conformant implementation of the
 IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2).
 .
 The Programmable Completion Code, by Ian Macdonald, is now found in
 the bash-completion package.

Indexes files present inside the /var/lib/apt/lists (Packages, Contents, Translation, sources...) directory are downloaded/updated when the apt update command is run.

  • To get infos about the installed or available versions for specific packages, and the source repository they are coming from, use:
$ apt policy <package_name_or_regex>

# Example:

$ apt policy bash
bash:
  Installed: 5.0-6ubuntu1.2
  Candidate: 5.0-6ubuntu1.2
  Version table:
 *** 5.0-6ubuntu1.2 500
        500 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages
        500 http://security.ubuntu.com/ubuntu focal-security/main amd64 Packages
        100 /var/lib/dpkg/status
     5.0-6ubuntu1 500
        500 http://archive.ubuntu.com/ubuntu focal/main amd64 Packages

The infos shown here are also retrieved from the indexes files present inside the /var/lib/apt/lists directory. Those indexes files are downloaded/updated using the apt update command.

Install, upgrade and remove packages

Before installing packages, the following command should be used to download packages indexes files (Packages, Contents, Translation, sources... files) from the configured sources. Those indexes files contain essential infos about packages. To download/update indexes files, the following command can be used:

$ apt update

Then, install packages:

# Latest available versions
$ apt install <package_name_or_regex_or_glob>

# Specific version
$ apt install <package_name>=<package_version>

# Examples

$ apt install nginx
$ apt install tree=1.8.0-1

To upgrade all packages to the latest available versions from the configured packages sources, use:

$ apt upgrade

New packages will be installed if required to satisfy dependencies but existing packages will never be removed.

To remove packages, whitout removing all configuration files, use:

$ apt remove <package_name_or_regex_or_glob>

# Example

$ apt remove nginx

To remove all packages data including configuraion files, use:

$ apt purge <package_name_or_regex_or_glob>

# Example:

$ apt purge tree

Purge debconf settings

Once a package using debconf is preconfigured, settings are stored in debconf database and not asked again when another preconfiguration is run. If the package has been installed, we can simply make a reconfigure in order to answer the questions again. But if its not installed, the only way to make debconf ask the configuration questions again is to remove the settings from its database. The following command can be used for that:

echo PURGE | debconf-communicate <package_name>

In the previous command, PURGE is a debconf command. Here is a list of debconf commands and their explanations.

debconf-communicate is a command line utility that can be used to communicate with debconf. Have a look at debconf-communicate for more.

Download binary packages and sources

  • Download binary packages (.deb)
$ apt download <package_name_or_regex>

# Example:

$ apt download tree
Get:1 http://archive.ubuntu.com/ubuntu focal/universe amd64 tree amd64 1.8.0-1 [43.0 kB]
Fetched 43.0 kB in 1s (84.9 kB/s)

$ ll *.deb
-rw-r--r-- 1 ubuntu ubuntu 43044 Dec 11  2018 tree_1.8.0-1_amd64.deb
  • Download packages sources archives, unpack and apply patches
$ apt source <package_name_or_regex>

# Example:

$ apt source tree
Reading package lists... Done
NOTICE: 'tree' packaging is maintained in the 'Git' version control system at:
https://salsa.debian.org/debian/tree-packaging.git
Please use:
git clone https://salsa.debian.org/debian/tree-packaging.git
to retrieve the latest (possibly unreleased) updates to the package.
Need to get 58.6 kB of source archives.
Get:1 http://archive.ubuntu.com/ubuntu focal/universe tree 1.8.0-1 (dsc) [1818 B]
Get:2 http://archive.ubuntu.com/ubuntu focal/universe tree 1.8.0-1 (tar) [50.3 kB]
Get:3 http://archive.ubuntu.com/ubuntu focal/universe tree 1.8.0-1 (diff) [6504 B]
Fetched 58.6 kB in 1s (99.7 kB/s)
dpkg-source: info: extracting tree in tree-1.8.0
dpkg-source: info: unpacking tree_1.8.0.orig.tar.gz
dpkg-source: info: unpacking tree_1.8.0-1.debian.tar.xz
dpkg-source: info: using patch list from debian/patches/series
dpkg-source: info: applying PATH_MAX
dpkg-source: info: applying manpage

$ ll tree*
drwxrwxr-x  5 ubuntu ubuntu  4096 Nov 13 02:08 ./
drwxrwxrwt 14 root   root    4096 Nov 13 02:10 ../
drwxrwxr-x  4 ubuntu ubuntu  4096 Nov 13 02:08 .pc/
-rw-r--r--  1 ubuntu ubuntu 12024 Nov 16  2018 CHANGES
-rw-r--r--  1 ubuntu ubuntu   597 Jan  4  2018 INSTALL
-rw-r--r--  1 ubuntu ubuntu 18009 Aug 12  2004 LICENSE
-rw-r--r--  1 ubuntu ubuntu  2973 Jan 18  2018 Makefile
-rw-r--r--  1 ubuntu ubuntu  5740 Jun 22  2015 README
-rw-r--r--  1 ubuntu ubuntu  2403 Feb 11  2015 TODO
-rw-r--r--  1 ubuntu ubuntu 16408 Nov 16  2018 color.c
drwxrwxr-x  4 ubuntu ubuntu  4096 Dec 11  2018 debian/
drwxrwxr-x  2 ubuntu ubuntu  4096 Nov 13 02:08 doc/
-rw-r--r--  1 ubuntu ubuntu  7497 Jan  9  2018 file.c
-rw-r--r--  1 ubuntu ubuntu  3151 Jan 10  2018 hash.c
-rw-r--r--  1 ubuntu ubuntu 14404 Jan 10  2018 html.c
-rw-r--r--  1 ubuntu ubuntu  9813 Jan 10  2018 json.c
-rw-r--r--  1 ubuntu ubuntu  5322 Aug 27  2008 strverscmp.c
-rw-r--r--  1 ubuntu ubuntu 36885 Nov 13 02:08 tree.c
-rw-r--r--  1 ubuntu ubuntu  5593 Jan 10  2018 tree.h
-rw-r--r--  1 ubuntu ubuntu  7651 Jan 10  2018 unix.c
-rw-r--r--  1 ubuntu ubuntu  9029 Nov 16  2018 xml.c
  • Download packages sources archive whithout unpacking
$ apt source --download-only <package_name_or_regex>

# Example:

$ apt source --download-only tree
Reading package lists... Done
NOTICE: 'tree' packaging is maintained in the 'Git' version control system at:
https://salsa.debian.org/debian/tree-packaging.git
Please use:
git clone https://salsa.debian.org/debian/tree-packaging.git
to retrieve the latest (possibly unreleased) updates to the package.
Need to get 58.6 kB of source archives.
Get:1 http://archive.ubuntu.com/ubuntu focal/universe tree 1.8.0-1 (dsc) [1818 B]
Get:2 http://archive.ubuntu.com/ubuntu focal/universe tree 1.8.0-1 (tar) [50.3 kB]
Get:3 http://archive.ubuntu.com/ubuntu focal/universe tree 1.8.0-1 (diff) [6504 B]
Fetched 58.6 kB in 1s (74.4 kB/s)
Download complete and in download only mode

$ ll tree*
-rw-r--r-- 1 ubuntu ubuntu  6504 Dec 11  2018 tree_1.8.0-1.debian.tar.xz
-rw-r--r-- 1 ubuntu ubuntu  1818 Dec 11  2018 tree_1.8.0-1.dsc
-rw-r--r-- 1 ubuntu ubuntu 50286 Dec 11  2018 tree_1.8.0.orig.tar.gz

Cleanup packages and packages cache

  • Remove downloaded packages files stored in /var/cache/apt/archives/:
$ apt clean
  • Remove downloaded packages files stored in /var/cache/apt/archives/ that can no longer be downloaded or became useless. A good command for maintaining caches over a long period while avoiding it to grow out of control:
$ apt autoclean
  • Remove/uninstall packages that were automatically installed to satisfy dependencies for other packages and are no longer needed:
$ apt autoremove

View binary packages (.deb) content

  • Show content tree whitout extracting
$ dpkg -c <.deb_file>

# Example:

$ dpkg -c tree_1.8.0-1_amd64.deb
drwxr-xr-x root/root         0 2018-12-11 11:19 ./
drwxr-xr-x root/root         0 2018-12-11 11:19 ./usr/
drwxr-xr-x root/root         0 2018-12-11 11:19 ./usr/bin/
-rwxr-xr-x root/root     85608 2018-12-11 11:19 ./usr/bin/tree
drwxr-xr-x root/root         0 2018-12-11 11:19 ./usr/share/
drwxr-xr-x root/root         0 2018-12-11 11:19 ./usr/share/doc/
drwxr-xr-x root/root         0 2018-12-11 11:19 ./usr/share/doc/tree/
-rw-r--r-- root/root      2723 2015-06-22 22:17 ./usr/share/doc/tree/README.gz
-rw-r--r-- root/root      2403 2015-02-11 21:57 ./usr/share/doc/tree/TODO
-rw-r--r-- root/root      2045 2018-12-11 11:19 ./usr/share/doc/tree/changelog.Debian.gz
-rw-r--r-- root/root      2441 2018-12-11 11:19 ./usr/share/doc/tree/copyright
drwxr-xr-x root/root         0 2018-12-11 11:19 ./usr/share/man/
drwxr-xr-x root/root         0 2018-12-11 11:19 ./usr/share/man/man1/
-rw-r--r-- root/root      4627 2018-12-11 11:19 ./usr/share/man/man1/tree.1.gz
  • Extract .deb files
$ ar x <.deb_file>

# Example:

$ ar x tree_1.8.0-1_amd64.deb 
$ ll
drwxrwxr-x 2 ubuntu ubuntu  4096 Nov 13 11:31 ./
drwxr-xr-x 5 ubuntu ubuntu  4096 Nov 13 11:31 ../
-rw-r--r-- 1 ubuntu ubuntu   836 Nov 13 11:31 control.tar.xz
-rw-r--r-- 1 ubuntu ubuntu 42016 Nov 13 11:31 data.tar.xz
-rw-r--r-- 1 ubuntu ubuntu     4 Nov 13 11:31 debian-binary

$ tar xfvJ data.tar.xz
./
./usr/
./usr/bin/
./usr/bin/tree
./usr/share/
./usr/share/doc/
./usr/share/doc/tree/
./usr/share/doc/tree/README.gz
./usr/share/doc/tree/TODO
./usr/share/doc/tree/changelog.Debian.gz
./usr/share/doc/tree/copyright
./usr/share/man/
./usr/share/man/man1/
./usr/share/man/man1/tree.1.gz

$ tar xfvJ control.tar.xz
./
./control
./md5sums

$ cat control
Package: tree
Version: 1.8.0-1
Architecture: amd64
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Florian Ernst <florian@debian.org>
Installed-Size: 112
Depends: libc6 (>= 2.4)
Section: utils
Priority: optional
Homepage: http://mama.indstate.edu/users/ice/tree/
Description: displays an indented directory tree, in color
 Tree is a recursive directory listing command that produces a depth indented
 listing of files, which is colorized ala dircolors if the LS_COLORS environment
 variable is set and output is to tty.

$ cat md5sums
5ad15c3f7e68891955c95f936160b4df  usr/bin/tree
f49004c1057dfeaed3db1dceb050ac5d  usr/share/doc/tree/README.gz
3eb175af3a5716275b668ce860c2bfad  usr/share/doc/tree/TODO
9f977a86aaf54b1358c92a392dadee23  usr/share/doc/tree/changelog.Debian.gz
e51a3c84c3b33325acc683347bfb4d3f  usr/share/doc/tree/copyright
e0fceaec1e51e1da23fce6741a21e5a4  usr/share/man/man1/tree.1.gz