Apt

From miki
Jump to navigation Jump to search

apt is the package management of Debian / Ubuntu.

Basic

NEW — Do not use apt-get anymore, use apt instead. Mostly the same, but with progress bar!

Install and update

Installing a package from REPOSITORIES, using aptitude:

# ----- Installing from the REPOSITORIES - APTITUDE
aptitude update                          # (OPTIONAL) update the local repository cache
aptitude install <package(s)>            # Install given package
aptitude remove <package(s)>             # Remove package (or install it if package name prefixed with - )

Note: Advantage of aptitude over apt-get is that it maintains /var/log/aptitude, and remove dependencies by default.

Installing a package from REPOSITORIES, using apt (a better version of apt-get):

# ----- Installing from the REPOSITORIES - APT
apt update                           # (OPTIONAL) update the local repository cache
apt list --upgradable                # See which package can be upgraded
apt install <package(s)>             # Install given package
apt install <package(s)>=<version>   # Use = to install a specific version (usually to force downgrade) !!! no space !!!
apt install <package(s)>/<release>   # Or use / to install from a specific distribution version !!! no space !!!
apt upgrade                          # Install new version of all installed package (without installing new package)
apt remove <package(s)>              # Remove package (or install it if package name prefixed with - )
apt autoremove <package(s)>          # Remove package and all its unused dependencies
apt purge <package(s)>               # Remove package and related configuration files
apt autoremove                       # Remove package installed to satisfy dependencies for some package and that are no more needed

Installing a package from a .deb PACKAGE file:

# ----- Installing from a .deb PACKAGE file
dpkg --install <debfile>                 # (or -i) Install a package from given .deb file
                                         # ... may require 'apt install -f'
apt install ./<debfile>                  # install from a give .deb, with dependencies.

Miscellaneous stuff:

apt-mark auto <package(s)>               # Mark package as AUTOMATICALLY installed (undo "set to manually installed")

Query

Querying the cache or installed packages:

# ----- Querying INSTALLED PACKAGE
dpkg --get-selections                    # Show the list of packages installed through apt-get
dpkg --get-selections | grep php         # ... filtering for some specific package keyword
dpkg -l <pattern>                        # (dpkg-query) List packages matching pattern, incl. version + description
dpkg -s <package>                        # (dpkg-query) Report status of specified package
dpkg -L <package>                        # List files delivered by a given <package>
dlocate -L <package>                     # ... same as above but much faster (require package dlocate)
dpkg -S <file>                           # List packages providing given file
dlocate -S <file>                        # ... same as above but much faster (require package dlocate)
dlocate <file>                           # ... same as dpkg -L -S combined but much faster (require package dlocate)
debsums -s <pacakge>                     # List MODIFIED files in given package
debsums -s                               # List MODIFIED files in all installed packages
# ----- Querying the CACHE
apt-cache search <regex>                 # Search package cache (package name and description) for given <regex>
apt-cache search --name-only <regex>     # ... same but only search in package name
apt-cache showpkg <package(s)>           # Show version and dependencies information about given package(s)
apt-cache show <package(s)>              # Show information (description...) about given package(s)
apt-cache dotty <package(s)>|dot -Tpng|display
                                         # Generate & display dependency graph (require graphviz & imagemagick)
apt-cache rdepends -d <package(s)>|dot -Tpng|display
                                         # Idem (but usually much lighter)
apt-cache dotty -o APT::Cache::GivenOnly=true $(dpkg --get-selections linux*|awk '{print $1}')|dot -Tpng|display
                                         # Dependency graph restricted to package(s) given on command line
aptitude why|why-not <package>           # Explain why a package should or cannot be installed on the system
apt-cache rdepends --installed --recurse --no-suggests --no-recommends --no-conflicts <package>
                                         # Same, using apt-cache
# ----- Querying a .deb PACKAGE file
dpkg --info <debfile>                    # (or -I) Show information of given .deb file
dpkg --content <debfile>                 # (or -c) Show content of given .deb file
# ----- Querying LIST of packages
deborphan -a | sort                      # List of all packages that have no dependencies
apt-show-versions                        # List all installed packages, and whether there are up-to-date, obsolete, not coming from repo
apt-show-versions -a                     # ... idem, but show all available versions
apt-show-versions | grep -v uptodate     # ... only show packages that are no up-to-date (No available version, upgradeable)
aptitude search '~o'                     # Similar to 'apt-show-versions' | grep 'No available version'

apt-mark showmanual                      # Show packages marked as manually installed
                                         # ... see also https://askubuntu.com/questions/2389/
apt-mark showhold                        # Show held packages

Querying packages that are not installed yet (may require package apt-file):

apt-file update                          # (optional - needed 1st time use)
apt-file list <package>                  # Search package in repositories, and show the content
apt-file search <file>                   # Display the name of all packages within repository that contain this file
apt-file search -l <file>                # ... only print package name
apt-file search -x "/<file>$"            # ... more accurate query using regex
#View package CHANGELOG
aptitude changelog <package>             # changelog of version that was/will be installed
aptitude changelog <package>=version     # ... specific version
Note: An alternative is to use the script [{{#file: dweblocate}} dweblocate], but apt-file is more powerful actually
#!/bin/bash

# Very handy script to query online debian/ubuntu package database.
# It more or less imitates the behaviour of dlocate, but is not limited to package installed on the current system.
#
# Usage:
#
#   dweblocate -L <package>   List all files in package <package>
#   dweblocate -S <filename>  List all packages that contains <filename>
#
# Based on script at http://mydebian.blogdns.org/?p=742
# Modified by Fuujuhi, 2009.

DIST=ubuntu                      # debian | ubuntu
SUITENAME=jaunty                 # Not necessary for debian

if [ "$DIST" = "ubuntu" ] ; then
        LISTURL="http://packages.ubuntu.com/$DISTNAME/all/$2/filelist"
        SEARCHURL="http://packages.ubuntu.com/search?suite=${SUITENAME}&searchon=contents&keywords=$2"
elif [ "$DIST" = "debian" ] ; then
        LISTURL="http://packages.ubuntu.com/$DISTNAME/all/$2/filelist"
        SEARCHURL="http://packages.debian.org/search?suite=stable&searchon=contents&keywords=$2"
else
        echo -e "Unknown distribution $DIST... Aborting!"
        exit 1
fi

if [ $# -lt 2 ]; then
        echo -e "Usage:\t$0 -S file \n\t$0 -L package"
        exit 1
fi

if [ "$1" = "-L" ]; then
        wget -q "$LISTURL" -O- | sed -n '/<pre>/,/<\/pre>/ {s/^[^/]*//;/\/pre>/!p}'
elif [ "$1" = "-S" ]; then
        wget -q "$SEARCHURL" -O- | sed -n '/<table>/,/<\/table>/ { s/[[:space:]]*<a href="[^>]*>\([^<]*\)<\/a>/\1/p}'
else
        echo "Error: invalid argument \"$1\"";
    exit 2
fi

Querying packages that take the most disk space [1].

wajig large           # Requires 'wajig' package
dpigs                 # Requires 'debian-goodies' package

View

View package source repository:

apt-cache madison <package>         # Display available version of a package in each repository

View package installation history:

grep install /var/log/dpkg.log      # Also check dpkg.log.1, etc.
sudo cat /var/log/apt/terl.log      # Also check 
sudo cat /var/log/apt/history.log

Repository

Add a repository:

vi /etc/apt/sources.list            # or edit files in /etc/apt/sources.list.d/
apt-get update

Add a package authentication key:

# In one command:
apt-key adv --keyserver keys.gnupg.net --recv-keys 648ACFD622F3D138

# In multiple:
gpg --keyserver keyserver.ubuntu.com --recv 247D1CFF  # (optional) Get the key from some keyserver
gpg --export --armor 247D1CFF | sudo apt-key add -    # Add the key

Miscellaneous:

dpkg-reconfigure popularity-contest                   # subscribe / unsubscribe to the package usage survey
apt-get moo                                           # Get super cow powers
aptitude moo                                          # Get super cow powers? try with -v, -vv

Add an CDROM/DVDROM installation media

Note that a better option is to mount the CDROM as a loop device, and access content via file:// URI (see further below).

# ADD media
sudo apt-cdrom -d=/media/cdrom add                                              # Here mount path is irrelevant
sudo mount /path/to/debian-8.7.1-amd64-DVD-1.iso /media/cdrom -o loop           # Mount *after* apt-cdrom because CD is ejected first
# Same for other DVD

# Install from media
sudo apt install ...
sudo mount /path/to/debian-8.7.1-amd64-DVD-1.iso /media/cdrom -o loop           # Mount *AT THE SAME* path as reported by apt install


See also Debian commands on Yobi.be.

Audit, monitoring

Debsums
  • Use debsums to check MD5 sums of installed packages.
Use debsums -l to get list of packages that do not have MD5 sums file.
Then silent mode could typically be used in a cronjob to scan installed files regularly and report errors.
debsums -l               # Report package without MD5 sums
debsums -s               # Silent mode, report only mismatching files
apt-listchanges
# Install
sudo apt install apt-listchanges
# Configure it
sudo dpkg-reconfigure apt-listchanges

Clean up

Restore system to base install

Restore a system as if it was installed fresh from release repositories.

# First make sure system is up-to-date
sudo apt update
sudo apt upgrade
# Install apt-show-versions and remove foreign packages
sudo apt install apt-show-versions lsb-release
sudo apt remove $(apt-show-versions | grep "No available version" | cut -d: -f1 )
# TODO: if the following is not empty, remove the reported packages
apt-show-versions | grep -v $(lsb_release -cs)
sudo apt autoremove
# Purge configuration files
sudo apt purge $(dpkg -l | grep -E '^rc' | awk '{print $2}')
# TODO: Check the following is empty:
dpkg -l | grep -Ev '^ii'

APT policy

Use apt-cache policy to view current package policy:

apt-cache policy          # Policy summary
apt-cache policy <pkg>    # Policy for a given <pkg>

Content of file /etc/apt/apt.conf.d/00default (or /etc/apt/apt.conf if that file doesn't exist):

APT::Default-Release "testing";

This changes the order of preference for packages. Here it says default=testing=wheezy, so:

apt-cache policy virtualbox-osevirtualbox-ose:
# Installed: (none)
# Candidate: 4.0.2-dfsg-1
# Version table:
#    4.0.4-dfsg-1+b1 0
#       500 http://ftp.be.debian.org/debian/ sid/main amd64 Packages
#    4.0.2-dfsg-1 0
#       990 http://ftp.be.debian.org/debian/ wheezy/main amd64 Packages
#    3.2.10-dfsg-1 0
#       500 http://ftp.be.debian.org/debian/ squeeze/main amd64 Packages

The number (500 vs 990) is giving the priority.

APT Pinning

Reference:

Priorities

This is (simplified) summary from man apt_preferences. By default, apt assigns the following priorities.

1 Version marked NotAutomatic: yes but not as ButAutomaticUpgrades: yes.
100 Installed version.
500 Version not in target release.
990 Version in target release.

The target release is the release given on command line (-t release) or in configuration file.

apt installs the package with highest priority, and if two packages have equal priority, it installs the one with highest version number. apt never downgrades a package except if priority is > 1000.

Examples

Simple /etc/apt/preferences file, to track Debian stable:

Package: *
Pin: release a=stable
Pin-Priority: 700

Package: *
Pin: release a=testing
Pin-Priority: 650

Package: *
Pin: release a=unstable
Pin-Priority: 600

Another example. Default release is lucid, but we pin git packages from natty:

Package: *
Pin: release a=natty-updates
Pin-Priority: 250

Package: *
Pin: release a=natty
Pin-Priority: 200

Package: etckeeper git git-core git-doc git-gui git-man git-svn gitk gitweb dpkg dpkg-dev build-essential
Pin: release a=natty-updates
Pin-Priority: 990

Package: etckeeper git git-core git-doc git-gui git-man git-svn gitk gitweb dpkg dpkg-dev build-essential
Pin: release a=natty
Pin-Priority: 900

Package: *
Pin: release a=lucid-backports
Pin-Priority: 400

Debian version numbering

Rebuild / Recompile a package

References: [2], [3]

# Install required packages
sudo apt-get install build-essential fakeroot dpkg-dev

# DEBIAN - need the following:
sudo apt install devscripts

# Create build directory
mkdir build
cd build

# Get package source (e.g. udisks)
# - See further down to solve gpg signature verification warning
apt-get source udisks

# Install all packages needed to build 'udisks' (aka. build deps)
sudo apt-get build-dep udisks

# (optional) Unpack Debian / Ubuntu source package (.dsc) - this is done automatically by apt-get
# First get gpg key, and export it as trusted keys (see http://askubuntu.com/questions/56841/gpg-cant-check-signature)
gpg --keyserver keyserver.ubuntu.com --recv-keys 7ADF9466
gpg --no-default-keyring -a --export 136B762D | gpg --no-default-keyring --keyring ~/.gnupg/trustedkeys.gpg --import -
# Second unpack the source package
dpkg-source -x udisks_1.0.4-5ubuntu2.1.dsc

# Go into package dir
cd udisks-1.0.4/

# (optional) Edit the files
vi src/device.c
# (optional) Change compilation settings
DEB_BUILD_OPTIONS="--enable-gui --enable-radio" fakeroot debian/rules binary
CC=gcc-3.4 DEB_BUILD_OPTIONS="--enable-gui --enable-radio" fakeroot debian/rules binary
# (optional, strongly suggested) Change package version
debchange --local foo --preserve --distribution precise-proposed "Force mount flag 'dmode=0500' for UDF filesystem."

# Rebuild the package
dpkg-buildpackage -rfakeroot -b

# Install the package
cd ..
dpkg -i udisks_1.0.4-5ubuntu2.1foo1_amd64.deb

Ignore dependencies, force package install

apt-get download overlay-scrollbar-gtk2:i386
sudo dpkg --ignore-depends overlay-scrollbar -i overlay-scrollbar-gtk2*.deb
sudo vi /var/lib/dpkg/status
# On line Depends: remove 'overlay-scrollbar' for package 'overlay-scrollbar-gtk2', architecture 'i386'
sudo apt-get install -f

Hold a package

Using dpkg [4]:

# Put a package on hold:
echo "<package-name> hold" | sudo dpkg --set-selections

# Remove the hold
echo "<package-name> install" | sudo dpkg --set-selections

# Display the status of your packages
dpkg --get-selections

# Display the status of a single package
dpkg --get-selections | grep "<package-name>"

Using apt:

# Hold a package:
sudo apt-mark hold <package-name>

# Remove the hold:
sudo apt-mark unhold <package-name>

Clone or repackage

dpkg-repack creates a .deb file out of a package that has already been installed. If any changes have been made to the package while it was unpacked (ie, files in /etc were modified), the new package will inherit the changes.

This utility can make it easy to copy packages from one computer to another, or to recreate packages that are installed on your system, but no longer available elsewhere, or to store the current state of a package before you upgrade it.

apt-get install dpkg-repack
dpkg-repack package

apt-clone can be used to clone/restore the packages on a apt based system.

apt-get install apt-clone

Create custom package

See usage of checkinstall in Source package.

Create local repositories

Here some basic instructions to create a new apt repository.

Repository on a file server (samba)

Here we assume that the packages will be stored on a file server that is accessed through samba.

  • First let's create our local package directory and copy some packages into it.
mkdir -p /smb/someserver/share/deb/local-bookworm   # Let's assume we use debian Bookworm
cp *.deb /smb/someserver/share/deb/local-bookworm
  • Create a Packages.gz file.
cd /smb/someserver/share/deb/local-bookworm                                # Let's assume we use debian Bookworm
dpkg-scanpackages -m . /dev/null local-bookworm/ | gzip -9c > Packages.gz  # We include multi-version
  • Add the repo in apt sources:
sudo vi /etc/apt/sources.list
# Add the line:
#
#    deb [trusted=yes] file:/smb/someserver/share/deb  local-bookworm/
  • Update and install
sudo apt update               # Note: make sure the samba share is world readable
sudo apt install PACKAGE...

Update a computer not connected to internet

Here we describe how to update a debian/ubuntu distribution on a computer not connected to internet (called the offline system), using another computer connected to internet (called the proxy system).

Via apt cache

This method assumes that both offline and proxy systems are identical. Here we will simply first install the packages on the proxy system, then upgrade the offline system.

  1. First sync offline and proxy
Copy the folders /etc/apt, /var/lib/apt from proxy to offline system. Make sure that these folders are identical. Delete the folder /var/cache/apt on the offline system, it will be generated at next invocation of apt.
  1. Install the packages on proxy system.
  2. Copy the content of /var/cache/apt/archives to offline system.
  3. Install the packages on offline system.
Make sure to use the exact same apt-get install command. If some packages are missing, you may force reinstall these packages on the proxy system to get back the corresponding packages.

Using apt-offline

See dedicated page Apt-offline.

Via CDROM

Add to etc/fstab:

/srv/debian-cd/10.3.0/amd64/debian-10.3.0-amd64-DVD-1.iso   /mnt/debian-10.3.0-amd64-DVD-1   udf,iso9660     ro,loop,noauto,x-systemd.automount,x-gvfs-hide,x-systemd.device-timeout=10,x-systemd.idle-timeout=1min,users,_netdev     0    0
/srv/debian-cd/10.3.0/amd64/debian-10.3.0-amd64-DVD-2.iso   /mnt/debian-10.3.0-amd64-DVD-2   udf,iso9660     ro,loop,noauto,x-systemd.automount,x-gvfs-hide,x-systemd.device-timeout=10,x-systemd.idle-timeout=1min,users,_netdev     0    0
/srv/debian-cd/10.3.0/amd64/debian-10.3.0-amd64-DVD-3.iso   /mnt/debian-10.3.0-amd64-DVD-3   udf,iso9660     ro,loop,noauto,x-systemd.automount,x-gvfs-hide,x-systemd.device-timeout=10,x-systemd.idle-timeout=1min,users,_netdev     0    0
# ...
/srv/debian-cd/10.3.0/i386/debian-10.3.0-i386-DVD-1.iso     /mnt/debian-10.3.0-i386-DVD-1    udf,iso9660     ro,loop,noauto,x-systemd.automount,x-gvfs-hide,x-systemd.device-timeout=10,x-systemd.idle-timeout=1min,users,_netdev     0    0
/srv/debian-cd/10.3.0/i386/debian-10.3.0-i386-DVD-2.iso     /mnt/debian-10.3.0-i386-DVD-2    udf,iso9660     ro,loop,noauto,x-systemd.automount,x-gvfs-hide,x-systemd.device-timeout=10,x-systemd.idle-timeout=1min,users,_netdev     0    0
/srv/debian-cd/10.3.0/i386/debian-10.3.0-i386-DVD-3.iso     /mnt/debian-10.3.0-i386-DVD-3    udf,iso9660     ro,loop,noauto,x-systemd.automount,x-gvfs-hide,x-systemd.device-timeout=10,x-systemd.idle-timeout=1min,users,_netdev     0    0
# ...

The lines above will auto-mount the iso drives when they are accessed, and unmount automatically after 1min. The auto-unmount is necessary to avoid the 90s timeout at shutdown if the iso files are on a network share (samba). This assumes the cd iso are at /srv/debian-cd.

Reload systemd daemon

sudo systemctrl daemon-reload

Create file /etc/apt/sources.list.d/dvdrom.list:

deb [trusted=yes arch=amd64] file:///mnt/debian-10.3.0-amd64-DVD-1 buster contrib main
deb [trusted=yes arch=amd64] file:///mnt/debian-10.3.0-amd64-DVD-2 buster contrib main
deb [trusted=yes arch=amd64] file:///mnt/debian-10.3.0-amd64-DVD-3 buster contrib main
deb [trusted=yes arch=amd64] file:///mnt/debian-10.3.0-amd64-DVD-4 buster contrib main
deb [trusted=yes arch=amd64] file:///mnt/debian-10.3.0-amd64-DVD-5 buster contrib main
deb [trusted=yes arch=i386] file:///mnt/debian-10.3.0-i386-DVD-1 buster contrib main
deb [trusted=yes arch=i386] file:///mnt/debian-10.3.0-i386-DVD-2 buster contrib main
deb [trusted=yes arch=i386] file:///mnt/debian-10.3.0-i386-DVD-3 buster contrib main
deb [trusted=yes arch=i386] file:///mnt/debian-10.3.0-i386-DVD-4 buster contrib main
deb [trusted=yes arch=i386] file:///mnt/debian-10.3.0-i386-DVD-5 buster contrib main
sudo apt update                                # Ignore errors about missing 'Packages'

chroot and debootstrap

debootstrap is a tool which will install a Debian base system into a subdirectory of another, already installed system.

Internals

/var/cache/apt/archives
Contains the latest packages installed via apt-get. Before downloading a package, apt checks whether the package is already available (and not corrupted) in that folder.
/var/cache/apt/srcpkgcache.bin
(From [5] and man apt.conf) srcpkgcache.bin includes the information containing in the files in /var/lib/apt/lists — aka all informations you get from the internet by deb and deb-src lines — these information are changed only on apt-get update.
/var/cache/apt/pkgcache.bin
pkgcache.bin on the other hand caches the information in srcpkgcache.bin + the informations extracted from the apt and dpkg status files. These change on every install/remove done by apt or directly by dpkg. So if only the status files are changed apt doesn't need to reparse the other informations again - and if no file was changed in between yet and the last call apt can directly load the pkgcache.bin file into memory.
/var/lib/apt
Contains the list of repository content (as selected in /etc/apt/sources.list and /etc/apt/sources.list.d, the trusted keyrings, etc.

Troubleshooting

Fixing broken dependencies

A generic script from SO:

apt-get update
apt-get clean
apt-get install -fy
dpkg -i /var/cache/apt/archives/*.deb
dpkg --configure -a
apt-get install -fy

Fixing "libc6:arm64 depends on libgcc1"

We got the following issue when debootstraping over an existing system:

apt-get install -f
# The following NEW packages will be installed:
#   libgcc1
# 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
# 2 not fully installed or removed.
# Need to get 0 B/31.3 kB of archives.
# After this operation, 114 kB of additional disk space will be used.
# Do you want to continue? [Y/n] y
# E: Cannot get debconf version. Is debconf installed?
# debconf: apt-extracttemplates failed: No such file or directory
# dpkg: dependency problems prevent configuration of
#  libc6:arm64: libc6:arm64 depends on libgcc1; however: 
#   Package libgcc1 is not installed.

Possible fixes:

Mainly doing dpkg-reconfigure debconf.
Edit /var/lib/dpkg/status:
Package: multiarch-support
Status: install ok unpacked
Change unpacked to installed. Then
sudo dpkg --configure --pending
sudo apt-get install --reinstall multiarch-support libgcc1 debconf

Dealing with APT locking

# https://blog.sinjakli.co.uk/2021/10/25/waiting-for-apt-locks-without-the-hacky-bash-scripts/
apt-get -o DPkg::Lock::Timeout=3 dist-upgrade