Title : Spring cleaning your Debian system

Author: cyr4x3

Date : 17 November 2022

Tags : linux

Introduction

I like to think of computers comparing them to houses. Buying new things for

your house or upgrading the things you already own may seem the most

straight-forward way to make your house a better place. Buying new furniture

can help your house look more modern, prettier and improve your overall quality

of life. Replacing old tools and household appliances for new ones may help you

accomplish some tasks in a more efficient way. You get the idea. The same can

be said about computers if we replace the terms 'furniture' and 'household

appliances' for 'software' and/or 'hardware'.

My point here is that, while of course a modern and new house can be really

convenient and desirable, a clean and well-organized house should be a

priority. It doesn't matter how new and cool your house is and how many gadgets

and fancy items you have in it if it isn't clean and organized. The same

happens with computers. For me, having a lot of tools or software installed and

readily available but not even using half of it or keeping software you don't

use anymore, cluttering your system with no real purpose at all, is the

equivalent of having a messy house with old stuff you'll never touch again and

with random items spread everywhere.

As with houses, with computers there's a time of the year when one should

really spend some time cleaning the mess that daily usage comes with. I'm not

talking only about removing old files and programs we no longer use, but also

removing the clutter that things like our package manager may've left behind

when performing tasks such as a version update (or `dist-upgrade`).

Although this article is mainly focused on Debian (and Debian-based

distributions) I'm sure you can find tools and commands that can be equivalent

to any other Linux distribution.

Where should we start?

In the same way that happens when you're spring cleaning your house, when

you're spring cleaning your computer you will regret not having the habit of

doing it regularly, as it'd require much less work. So my first tip would be to

have the habit of keeping your system clean, with only the things you need.

In the next few sections I'll go over some of the commands you may want to use

for cleaning up your Debian system. You can go through all of them when you

feel like it, as there's no wrong time for cleaning up your computer. However

and as I said before, doing so before and after you perform a `dist-upgrade`

(or a big upgrade in general) is highly recommended.

Before we start, I advise you to read carefully through the output of every

command you type in the terminal, don't just answer yes to every prompt and

don't blindly believe me on everything. Read the warnings and understand every

command you type before confirming any action. I'm not responsible for the

damage that your actions may cause to your machine(s).

First sweep through

The first and more basic thing one can think of when cleaning up a system is

removing unused stuff, whether it is personal files or packages. If you want to

free up some space in your computer and you have a ton of movies, TV series,

games and music in your hard drive (legally downloaded, ofc ;) ) that you've

already played and watched, that may be the first thing you need to check. For

this task `du` and/or `ncdu` (a ncurses interface for `du`) may come in handy.

They'll show you how much space are your files taking up, so you can choose

whether to remove them or not.

If you're not a really organized person you may also have duplicated files in

your computer. Maybe, when downloading stuff from the internet, you download

the same document several times and forget to delete the duplicates, for

example. In that case, please stop. But how do you clean the mess that you

already have? Well, `czkawka` has got you covered. This program is, as

described in its GitHub page, "a simple, fast and free app to remove

unnecessary files from your computer". It has a CLI version as well as a GUI

one, which are quite intuitive. You may want to add this program to your set of

tools for spring cleaning.

Czkawka (GitHub)

Okay, enough talk about personal files, what about system packages? The same

logic applies. I recommend deleting everything you don't need and/or don't plan

to use ever again. Ask yourself these questions: do I really need having all

these desktop environments and/or window managers when I always log in to the

same one? Do I really need all these pieces of software that I once installed

to play around with and never used ever again? I'm not saying you should

uninstall everything you don't use on a daily basis, as you may want to keep

some stuff that may come in handy when the time comes, but knowing what you

have installed and why it is installed is always a good thing.

There are different approaches for tackling this problem. The first one, and

the one that makes more sense if you're desperate to free up some space, would

be to have a list of all the packages currently installed (through apt) and

sort them by the space they're taking up. Once you have this list, you can

start deleting packages you no longer need, starting with the big ones. This

list can be obtained with this simple command:

    $ dpkg-query -Wf '${Installed-Size} ${Package}\n' | sort -rn

Another simple and clean option is using a Perl script called `ds`, written by

Greg Wooledge, that does basically the same thing as the command shown above

with the main difference that it won't list anything that's in state

"deinstall" ("rc" on `dpkg -l`).

ds script

Greg's Domain

Remove all that clutter

The easiest thing we can do to remove the clutter that the apt package manager

may've stored in our hard drives, is the following:

    $ sudo apt autoremove --purge && sudo apt-get clean && sudo apt-get autoclean

The `autoremove` option is used to remove packages that were automatically

installed to satisfy dependencies of a package that has since then been removed

[^1] or has changed its dependencies. In case you want to keep some of these

dependencies, mark them as manually installed with `apt-mark`.

The `clean` option, on the other hand, clears out the local repository of

retrieved package files. On the other hand, `autoclean` only removes package

files that can no longer be downloaded, and are largely useless. So maybe

entering both commands, while not being harmful to your system, may be a bit

repetitive.

By default, removing a package with `remove` or `autoremove` doesn't delete its

configuration file(s). In case you don't plan on ever using again the programs

you uninstall or just don't want to keep the config files, `purge` is

recommended. When using `autoremove --purge` unnecessary automatically

installed packages will be purged (removed along with their configuration

files).

In case you removed or auto-removed packages in the past without purging them,

the following command should remove the remaining configuration files of

programs that have been deleted:

    $ dpkg -l | grep '^rc' | awk '{print $2}' | xargs sudo apt-get -y purge

Before running the previous command you may want to take a look at the list of

programs which are not installed but have remaining configuration files. This

can be achieved by simply removing the command after the last pipe:

    $ dpkg -l | grep '^rc' | awk '{print $2}'

One could also go one step further and delete every package that was installed

because another package recommended it but isn't a dependency of any installed

package. A list of all these packages can be obtained by typing:

    $ aptitude search '?and(?automatic(?reverse-recommends(?installed)), ?not(?automatic(?reverse-depends(?installed))))'

And in case you want to delete them all, you can do so by:

    $ aptitude search '?and( ?automatic(?reverse-recommends(?installed)), ?not(?automatic(?reverse-depends(?installed))) )' | awk '{ print $3 }' | xargs dpkg -P

An upgrade of a package may also bring some changes related to configuration

files (deprecated settings, change of syntax, etc.). When `apt` notices this,

it usually asks the user what to do: overwrite the old config file, backup the

old config file and create a new one for the new version of the package or do

nothing. Usually, the user will want to keep the custom config file that he had

before the upgrade until he can adapt it to work with new version, so the

second option is chosen most of the times. Once the user has modified and

tweaked the new configuration file, keeping a backup of an older version makes

little to no sense. To avoid confusion one may want to delete these leftover

files, along with versions supplied by the package maintainers and other unused

copies. These leftover files can be found with:

    $ sudo find /etc -name '*.dpkg-*' -o -name '*.ucf-*' -o -name '*.merge-error'

Orphaned packages

A very popular tool for cleaning up your system is `deborphan`. `deborphan`

searches for packages that have no other packages depending on them and were

installed as a dependency or recommendation for a package no longer present on

the system. When executing `deborphan` with no additional flags, a list of

packages will be printed to `stdout`. Once you're sure you can remove all of

them, you can do so by typing:

    $ deborphan | xargs sudo apt-get purge -y

One could also add the `--guess-all` flag to `deborphan`, to make it try to

figure which packages are of little to no use to you by examining the package's

name and description. You must be really careful when using this flag and I

only recommend it if you really know what you're doing. Please, read the

package list outputted by `deborphan` before piping it to `apt-get purge`.

Obsolete packages

The `apt-show-versions` utility lists the versions of the packages present on

your distro. In a similar way that `aptitude versions`, but with in a more

convenient way for our use case.

By entering `apt-show-versions` in a shell prompt, a list of all the currently

installed packages will be printed out. Note that this only includes packages

installed with the `apt` package manager (or `aptitude` or `nala`), and not

things like snaps or flatpaks. A sample of this output could be something like:

    ...
    sbcl:amd64/bullseye 2:2.1.1-2 uptodate
    sbcl:i386 not installed
    screenkey:all/bullseye 1:1.4-2 uptodate
    sed:amd64/bullseye 4.7-1 uptodate
    sed:i386 not installed
    sensible-utils:all/bullseye 0.0.14 uptodate
    sent:amd64/bullseye 1-3+b1 uptodate
    sent:i386 not installed
    ...

We can then see that the list is formatted in a specific way that we can take

advantage of.

    [name of the package]:[architecture]/[distribution] [package version] [updates]

Where `[updates]` simply checks if the package is or isn't on the latest

version available in the Debian repos corresponding to the current Debian

version that the system is running.

There's a series of packages that display their info in a different way. This

includes packages that were installed by a `.deb` file downloaded from the

internet, packages installed from `apt` sources that are no longer available

(they no longer figure in `/etc/apt/sources.list` nor

`/etc/apt/sources.list.d/`) and packages from previous Debian versions that have

changed their name in more recent ones and haven't been replaced, leaving the

two versions, which `apt` interprets as two different packages, coexisting. In

other words these are packages that Debian can't find in their repositories or

the ones you may've added in `/etc/apt/sources.list`. An example could be:

    linux-image-4.19.0-21-amd64:amd64 4.19.249-2 installed: No available version in archive

This package corresponds to the latest kernel version I used before updating to

Debian 11. Right now I'm using version 5.10.0-19 (the latest one available in

Debian stable as of now), but this package wasn't removed. We can get a list of

all the packages that Debian can't find a list for with:

    $ apt-show-versions | grep 'No available'

After taking a look at the listed packages you may want to remove some of them

manually. In case you'd like to remove all of them, something like this should

work for the example using `apt-show-versions`:

    $ apt-show-versions | grep 'No available' | awk -F' ' '{ print $1}' | xargs sudo apt-get purge -y

If you prefer not to use `apt-show-versions`, a similar (or nearly identical)

list can be obtained with:

    $ aptitude search '~o'

This will search for packages marked as "obsolete" by the aptitude.

Non-Debian packages

Now let's imagine you installed a bunch of software from third party

repositories that you may want to uninstall now. Maybe you installed a ton of

packages from `.deb` files downloaded from sketchy websites or added a bunch of

entries to your `sources.list` that you no longer want to have. First of, let

me tell you that was a bad idea and that you should always install software

through your distro package manager and from the official repos when possible.

Once that's been said, you could try and list all the installed packages that

didn't come from the official Debian repository.

The Debian 11 release notes suggests two different commands to do exactly that.

    $ aptitude search '?narrow(?installed, ?not(?origin(Debian)))'

This will also include packages that were once provided by Debian but no longer

are (e.g. old kernel packages).

The other option is using `apt-forktracer`, a utility for managing package

versions.

    $ apt-forktracer | sort

Transitional dummy packages

Transitional dummy packages are meant to simplify the transition when a package

is renamed. If a package called `package-old` is renamed to `package-new`from a

release to another, without a transitional package, the package manager will

treat `package-new` as a completely different program than `package-old` and

not its newer version. User users who already had `package-old` installed won't

receive any updates, as the package manager does not see the relation between

`package-old` and `package-new`.

Transitional packages try to prevent this kind of behaviour. The package

maintainer just needs to create a transitional package called `package-old`

without any files nor contents that has `package-new` as its only dependency.

By doing this, if someone updates `package-old` it will update to this

transitional package and, therefore, `package-new` will be installed as a

requirement. These empty packages (containing only metadata) whose sole purpose

is to install other packages by having them as a requirement are also referred

to as "meta packages".

These transitional dummy packages are, most of the times, useless once the name

change has been done (i.e. the transition has been completed), so we can remove

them.

One can see the dummy packages present in its system by doing:

    $ dpkg -l | grep ^ii | grep -i -E "(transition|dummy)"

Alternatively, one can use `deborphan`:

    $ deborphan --guess-dummy

Take into account that, as the `deborphan(1)` man page states, these guess

flags for `deborphan` are not perfect, so be extremely cautious when deleting

some of the packages listed in there.

Final notes

These would be some of the things I'd do in order to clean up a bit a Debian

system. Sometimes less is more and having a clean system with only the things

you need is key administrate it in the most efficient way.

If you have any suggestions, corrections and/or comments you'd like to send me,

feel free to email them to me.

Resources and references

The Debian Administrator's Handbook - Section 6.7

Debian 11 Release Notes - Section 4.2

Debian Bug report logs - #987017

Man pages of all the software mentioned.

[^1]: When uninstalling software that had some dependencies, apt already

prompts us by saying that there are some packages which are not required

anymore (those dependencies) and can be uninstalled with `apt autoremove`.