Submitted by alexios on

You have a Debian, Ubuntu or similar installation, and your /var partition keeps getting full when you upgrade. You check /var/cache/apt/archives and find it full of the usual mix of current and old versions of downloaded packages. Somehow, they haven't been deleted after installation, or you keep downloading them but not installing them. You now need a quick and clever way of cleaning up this mess, so only the latest version of each package remains.

Solution

Here's an appropriate bash invocation:

for a in `ls /var/cache/apt/archives | grep '.deb$' | cut -d _ -f1 | sort | uniq`; do ls -tr /var/cache/apt/archives/${a}_* | sed '$ d' | xargs -r -p sudo rm -v done

For each package name, this will delete all but the latest .deb package. Obviously, if there's only one version of a package, it's not deleted. You will be asked to confirm each deletion.

If you're running this as root (naughty, naughty), remove the sudo from the second line. On Ubuntu, sudo is already set up for you, and you should use it. On Debian, you need to install and set it up yourself.

Discussion

Debian package names can't contain an underscore (_). Everything that comes after the underscore in a .deb filename is version (and platform) information. The back-quoted part of the first line locates all package name stems. By performing ls | grep rather than using something like ls /var/cache/apt/archives/*.deb, we avoid failure in case there are too many packages for the command line1.

Then, on the second line, we list everything that starts with that package name, order it by increasing timestamp (latest files last), and use sed to delete the last line (most recent file). All filenames thus nominated are deleted using the xargs sudo rm invocation. The -r option avoids running sudo rm with no arguments.

This script runs rm verbosely and interactively, using the -v (for rm) and -p (for xargs) options respectively. Every deletion is printed out, and you're asked to confirm each one. Then, the actual deletions are printed out. If this gets too much (it often does), remove the -v option. To remove interactivity and delete without checking, just remove the -p from xargs (or insert yes | before the for keyword on the first line).

  • 1. On Linux, the maximum command line length varies. Before Linux 2.6.23, it used to be 131,072 bytes. Starting with Linux 2.6.23, there is no limit in the kernel, but it still reports the traditional limit anyway (tell bash getconf ARG_MAX to find out what it is). We shouldn't rely on this.

Tags: 


Comments


Add new comment

Leave a comment