Introduction

In our earlier articles on package management for Debian bases distributions, we’ve covered dpkg, apt-get, and apt-cache tools. In this article, we will cover the apt tool for managing packages on our Ubuntu 16.04 system. The command line options for apt are very similar to those available with apt-get and apt-cache because apt encompasses features of both these tools into one package management tool. Apt is a front-end tool which works with dpkg in the background to maintain software on the system.

To interact with the apt package manager, we use the apt command along with the appropriate options.
We’ll now take you through some examples to help understand how we use the apt package manager.

Example 1: Update local cache
The system queries online remote and local repositories and maintains a cache of information about packages available in these repositories. This cache could be regarded as an index of available packages in the online repositories. The names and URLs of these online repositories are maintained in /etc/apt/sources.list file.
Given below is a snippet from the file on my local system:

root@linuxnix:~# cat /etc/apt/sources.list | grep -Ev '^#|^$|ec2'
deb http://security.ubuntu.com/ubuntu xenial-security main restricted
deb-src http://security.ubuntu.com/ubuntu xenial-security main restricted
deb http://security.ubuntu.com/ubuntu xenial-security universe
deb-src http://security.ubuntu.com/ubuntu xenial-security universe
deb http://security.ubuntu.com/ubuntu xenial-security multiverse
deb-src http://security.ubuntu.com/ubuntu xenial-security multiverse

We can update that cache using the apt update command. Periodically updating the cache ensures that any new packages or package updates available in the repositories are also updated in the local cache.

root@linuxnix:~# apt update
Hit:1 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial InRelease
Hit:2 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial-updates InRelease
Hit:3 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial-backports InRelease
Hit:4 http://security.ubuntu.com/ubuntu xenial-security InRelease
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.
root@linuxnix:~#

Example 2: System update
To update all packages installed on the system to their latest version, we use the apt upgrade command.

root@linuxnix:~# apt upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following packages were automatically installed and are no longer required:
libblas-common libblas3 liblinear3 liblua5.2-0 libxslt1.1 linux-aws-headers-4.4.0-1032 linux-headers-4.4.0-1032-aws
linux-image-4.4.0-1032-aws lua-lpeg ndiff python-bs4 python-chardet python-html5lib python-lxml python-pkg-resources python-six
Use 'apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
root@linuxnix:~#

Example 3: Update all packages including the kernel
The apt upgrade command updates all packages on the system for which updates are available except for the Linux kernel.
If you wish to update the Linux kernel as well then use the apt dist-upgrade command as shown below.

root@linuxnix:~# apt dist-upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following packages were automatically installed and are no longer required:
libblas-common libblas3 liblinear3 liblua5.2-0 libxslt1.1 linux-aws-headers-4.4.0-1032 linux-headers-4.4.0-1032-aws
linux-image-4.4.0-1032-aws lua-lpeg ndiff python-bs4 python-chardet python-html5lib python-lxml python-pkg-resources python-six
Use 'apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
root@linuxnix:~#

Example 4: Search for a package
To search for a package we use the apt search command followed by the package name.
Let’s search for the zsh shell package.

root@linuxnix:~# apt search zsh
Sorting... Done
Full Text Search... Done
csh/xenial 20110502-2.1ubuntu1 amd64
Shell with C-like syntax
direnv/xenial 2.7.0-1 amd64
Utility to set directory specific environment variables
-----------------------output truncated for brevity
zsh-common/xenial 5.1.1-1ubuntu2 all
architecture independent files for Zsh
-----------------------output truncated for brevity

As you may observe from the output, apt performs a fuzzy match for the package name being searched i.e. it matches complete names, part of the package name and also the package description.
The resulting output shows some information about the matches found like the name, source repository, version and architecture followed by a one-line description of the package in the next line.

Example 5: Get information about a package
We use the apt show command to obtain information about a package.
Let’s display information about the zsh shell we searched for in the previous example.

root@linuxnix:~# apt show zsh
Package: zsh
Version: 5.1.1-1ubuntu2
Priority: optional
Section: shells
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian Zsh Maintainers <pkg-zsh-devel@lists.alioth.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 2,023 kB
Pre-Depends: dpkg (>= 1.17.14)
Depends: zsh-common (= 5.1.1-1ubuntu2), libc6 (>= 2.15), libcap2 (>= 1:2.10), libtinfo5 (>= 6)
Recommends: libncursesw5 (>= 6), libpcre3
Suggests: zsh-doc
Homepage: http://www.zsh.org/
Supported: 5y
Download-Size: 651 kB
APT-Sources: http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/main amd64 Packages
Description: shell with lots of features
Zsh is a UNIX command interpreter (shell) usable as an
interactive login shell and as a shell script command
processor. Of the standard shells, zsh most closely resembles
ksh but includes many enhancements. Zsh has command-line editing,
built-in spelling correction, programmable command completion,
shell functions (with autoloading), a history mechanism, and a
host of other features.

This command displays a lot of information about the package including it’s installed state, any dependencies required and also details about conflicts with other packages.

Example 6: Install a package
To install a new package we use the apt install command followed by the package name.
Let’s install the zsh shell package we’ve used in our earlier examples to demonstrate.

root@linuxnix:~# apt install zsh
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
zsh-common
Suggested packages:
zsh-doc
The following NEW packages will be installed:
zsh zsh-common
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 3,822 kB of archives.
After this operation, 14.2 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/main amd64 zsh-common all 5.1.1-1ubuntu2 [3,170 kB]
Get:2 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/main amd64 zsh amd64 5.1.1-1ubuntu2 [651 kB]
Fetched 3,822 kB in 1s (3,195 kB/s)
Selecting previously unselected package zsh-common.
(Reading database ... 108061 files and directories currently installed.)
Preparing to unpack .../zsh-common_5.1.1-1ubuntu2_all.deb ...
Unpacking zsh-common (5.1.1-1ubuntu2) ...
Selecting previously unselected package zsh.
Preparing to unpack .../zsh_5.1.1-1ubuntu2_amd64.deb ...
Unpacking zsh (5.1.1-1ubuntu2) ...
Processing triggers for man-db (2.7.5-1) ...
Setting up zsh-common (5.1.1-1ubuntu2) ...
Setting up zsh (5.1.1-1ubuntu2) ...
update-alternatives: using /bin/zsh5 to provide /bin/zsh (zsh) in auto mode
update-alternatives: using /bin/zsh5 to provide /bin/rzsh (rzsh) in auto mode
root@linuxnix:~#

If you were to run the apt show command for the zsh shell again you would now see an additional line “APT-Manual-Installed: yes” confirming the status of the package as installed.

Example 7: Remove a package
To remove a package we use the apt remove command followed by the package name.
Let’s demonstrate by removing the zsh shell package we installed in the previous example.

root@linuxnix:~# apt remove zsh
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
libblas-common libblas3 liblinear3 liblua5.2-0 libxslt1.1 linux-aws-headers-4.4.0-1032 linux-headers-4.4.0-1032-aws
linux-image-4.4.0-1032-aws lua-lpeg ndiff python-bs4 python-chardet python-html5lib python-lxml python-pkg-resources python-six
zsh-common
Use 'apt autoremove' to remove them.
The following packages will be REMOVED:
zsh
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 2,023 kB disk space will be freed.
Do you want to continue? [Y/n] Y
(Reading database ... 109329 files and directories currently installed.)
Removing zsh (5.1.1-1ubuntu2) ...
root@linuxnix:~#

 

Example 8: Purge a package
Using apt remove to delete a package removes the package binaries but leaves the configuration files.
To remove the configuration files as well, use the apt purge command followed by the package name.
Note that you can run apt purge command on already removed packages.
We’ll now perform and apt purge on the zsh package

root@linuxnix:~# apt purge zsh
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
libblas-common libblas3 liblinear3 liblua5.2-0 libxslt1.1 linux-aws-headers-4.4.0-1032 linux-headers-4.4.0-1032-aws
linux-image-4.4.0-1032-aws lua-lpeg ndiff python-bs4 python-chardet python-html5lib python-lxml python-pkg-resources python-six
zsh-common
Use 'apt autoremove' to remove them.
The following packages will be REMOVED:
zsh*
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 2,023 kB disk space will be freed.
Do you want to continue? [Y/n] Y
(Reading database ... 109329 files and directories currently installed.)
Removing zsh (5.1.1-1ubuntu2) ...
Purging configuration files for zsh (5.1.1-1ubuntu2) ...
root@linuxnix:~#

Example 9: Search for specific package name only
The apt search command which we demonstrated earlier performs a regex search for matching package names.
If you’d like to limit the search to the specific package only then use the apt list command.

root@linuxnix:~# apt list zsh
Listing... Done
zsh/xenial 5.1.1-1ubuntu2 amd64
root@linuxnix:~#

Example 10: List all installed packages
To display a list of all packages currently installed on the system use the following command.

root@linuxnix:~# apt list --installed
Listing... Done
accountsservice/xenial-updates,now 0.6.40-2ubuntu11.3 amd64 [installed]
acl/xenial,now 2.2.52-3 amd64 [installed]
acpid/xenial,now 1:2.0.26-1ubuntu2 amd64 [installed]
adduser/xenial,now 3.113+nmu3ubuntu4 all [installed]
amazon-ssm-agent/now 2.2.93.0-1 amd64 [installed,local]
apparmor/xenial-updates,now 2.10.95-0ubuntu2.7 amd64 [installed]
apport/xenial-updates,now 2.20.1-0ubuntu2.14 all [installed]
apport-symptoms/xenial,now 0.20 all [installed]
apt/xenial-updates,now 1.2.24 amd64 [installed]
apt-transport-https/xenial-updates,now 1.2.24 amd64 [installed]
apt-utils/xenial-updates,now 1.2.24 amd64 [installed]
at/xenial,now 3.1.18-2ubuntu1 amd64 [installed]
-------------------------------output truncated for brevity

Example 11: List dependencies for a package
To list dependencies for a package use the apt depends command followed by the package name.

root@linuxnix:~# apt depends zsh
zsh
PreDepends: dpkg (>= 1.17.14)
Depends: zsh-common (= 5.1.1-1ubuntu2)
Depends: libc6 (>= 2.15)
Depends: libcap2 (>= 1:2.10)
Depends: libtinfo5 (>= 6)
Recommends: libncursesw5 (>= 6)
Recommends: libpcre3
Suggests: zsh-doc

Example 12: Download packages without installation
To download a package to the current working directory without installation, use the apt download command followed by the package name.
Let’s download the zsh package.

root@linuxnix:~# apt download zsh
Get:1 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/main amd64 zsh amd64 5.1.1-1ubuntu2 [651 kB]
Fetched 651 kB in 0s (17.5 MB/s)
downloading as file '/root/zsh_5.1.1-1ubuntu2_amd64.deb' 
root@linuxnix:~# ls -l zsh_5.1.1-1ubuntu2_amd64.deb
-rw-r--r-- 1 root root 651294 Feb 7 2016 zsh_5.1.1-1ubuntu2_amd64.deb
root@linuxnix:~#

Although the next three examples that we’re about to demonstrate do not use the apt tool, we decided to include them for a complete feature set representation of the package management features in the Ubuntu operating system.

Example 13: Lock a package
We can prevent a package from being upgraded by Ubuntu by locking it to the currently installed version.
We achieve this by using the apt-mark hold command followed by the package name.
Let’s lock the sudo package to demonstrate.

root@linnuxnix:~# apt-mark hold sudo
sudo set on hold.

Example 14: Unlock a package
To unlock a package we use the apt-mark unhold command followed by the package name.
This makes the package available for subsequent updates performed using the apt upgrade command.
We’ll unhold the sudo package now.

root@linnuxnix:~# apt-mark unhold sudo
Canceled hold on sudo.

Example 15: View package content
We can use the dpkg -L command or the dpkg -c command to query the files that were installed by a package but to obtain the same information about a package in an internet repository, we need to use the apt-file command.
This is not available by default, so let’s install it first.

root@linnuxnix:~# apt install apt-file
Reading package lists... Done
Building dependency tree
Reading state information... Done
linux-image-4.4.0-1032-aws lua-lpeg ndiff python-bs4 python-chardet python-html5lib python-lxml python-pkg-resources python-six
zsh-common
Use 'apt autoremove' to remove them.
The following additional packages will be installed:
libapt-pkg-perl libconfig-file-perl libexporter-tiny-perl liblist-moreutils-perl libregexp-assemble-perl
The following NEW packages will be installed:
apt-file libapt-pkg-perl libconfig-file-perl libexporter-tiny-perl liblist-moreutils-perl libregexp-assemble-perl
0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
Need to get 270 kB of archives.
After this operation, 881 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/universe amd64 libconfig-file-perl all 1.50-3 [9,722 B]
Get:2 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/main amd64 libapt-pkg-perl amd64 0.1.29build7 [65.3 kB]
Get:3 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/main amd64 libexporter-tiny-perl all 0.042-1 [28.8 kB]
Get:4 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/main amd64 liblist-moreutils-perl amd64 0.413-1build1 [67.0 kB]
Get:5 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/universe amd64 libregexp-assemble-perl all 0.36-1 [77.5 kB]
Get:6 http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu xenial/universe amd64 apt-file all 2.5.5ubuntu1 [21.6 kB]
Fetched 270 kB in 2s (102 kB/s)
Selecting previously unselected package libconfig-file-perl.
(Reading database ... 109281 files and directories currently installed.)
Preparing to unpack .../libconfig-file-perl_1.50-3_all.deb ...
Unpacking libconfig-file-perl (1.50-3) ...
Selecting previously unselected package libapt-pkg-perl.
Preparing to unpack .../libapt-pkg-perl_0.1.29build7_amd64.deb ...
Unpacking libapt-pkg-perl (0.1.29build7) ...
Selecting previously unselected package libexporter-tiny-perl.
Preparing to unpack .../libexporter-tiny-perl_0.042-1_all.deb ...
Unpacking libexporter-tiny-perl (0.042-1) ...
Selecting previously unselected package liblist-moreutils-perl.
Preparing to unpack .../liblist-moreutils-perl_0.413-1build1_amd64.deb ...
Unpacking liblist-moreutils-perl (0.413-1build1) ...
Selecting previously unselected package libregexp-assemble-perl.
Preparing to unpack .../libregexp-assemble-perl_0.36-1_all.deb ...
Unpacking libregexp-assemble-perl (0.36-1) ...
Selecting previously unselected package apt-file.
Preparing to unpack .../apt-file_2.5.5ubuntu1_all.deb ...
Unpacking apt-file (2.5.5ubuntu1) ...
Processing triggers for man-db (2.7.5-1) ...
Setting up libconfig-file-perl (1.50-3) ...
Setting up libapt-pkg-perl (0.1.29build7) ...
Setting up libexporter-tiny-perl (0.042-1) ...
Setting up liblist-moreutils-perl (0.413-1build1) ...
Setting up libregexp-assemble-perl (0.36-1) ...
Setting up apt-file (2.5.5ubuntu1) ...
The system-wide cache is empty. You may want to run 'apt-file update'
as root to update the cache. You can also run 'apt-file update' as
normal user to use a cache in the user's home directory.
root@linnuxnix:~#

The apt-file utility also maintains a cache which is empty at initial install.
To update its cache we use the following command:

root@linnuxnix:~# apt-file update
Downloading complete file http://ap-southeast-1.ec2.archive.ubuntu.com/ubuntu/dists/xenial/Contents-amd64.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 31.7M 100 31.7M 0 0 52.1M 0 --:--:-- --:--:-- --:--:-- 52.0M
-------------------------------------------------------------------output truncated for brevity

Now let’s query what files make up the nmap package using the apt-file list command

root@linnuxnix:~# apt-file list nmap
libnmap-parser-perl: /usr/share/doc/libnmap-parser-perl/README
libnmap-parser-perl: /usr/share/doc/libnmap-parser-perl/changelog.Debian.gz
libnmap-parser-perl: /usr/share/doc/libnmap-parser-perl/copyright
libnmap-parser-perl: /usr/share/doc/libnmap-parser-perl/examples/nmap2sqlite.pl.gz
libnmap-parser-perl: /usr/share/doc/libnmap-parser-perl/examples/scan.pl.gz
libnmap-parser-perl: /usr/share/man/man3/Nmap::Parser.3pm.gz
libnmap-parser-perl: /usr/share/perl5/Nmap/Parser.pm
nmap: /usr/bin/ncat
nmap: /usr/bin/nmap
nmap: /usr/bin/nping
nmap: /usr/share/doc/nmap/3rd-party-licenses.txt.gz
-----------------------------------------------------output truncated for brevity

As evident from the above output, the apt-file utility is very useful for obtaining the list of files that would make up a package.

Conclusion

This concludes our exploration of the apt package management tool for Debian/Ubuntu systems.
We encourage you to use the apt package manager over apt-get and apt-cache tools since apt combines the functionality of both utilities into one.

The following two tabs change content below.

Sahil Suri

He started his career in IT in 2011 as a system administrator. He has since worked with HP-UX, Solaris and Linux operating systems along with exposure to high availability and virtualization solutions. He has a keen interest in shell, Python and Perl scripting and is learning the ropes on AWS cloud, DevOps tools, and methodologies. He enjoys sharing the knowledge he's gained over the years with the rest of the community.