Cleaning Up a Debian APT Archive Cache
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:
find /var/cache/apt/archives/ -name '*deb' |
perl -ne 'print "$1\n" if /([^\/_]+)_/'|
sort -u |
while read a; do
find /var/cache/apt/archives/ -name "${a}_*" |
sort -r | tail -n+1 | xargs -rp 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.
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 first three lines of the script locate all packages
and get their unique name stems. By using find 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. It's also a very bad idea to parse ls> output.
The second line finds everything between the last / and
first _ of each line and prints that out. This is the package name.
The third line collects all of the package names, sorts them and prints out unique names so we don't duplicate any effort.
Then, the while…done loop reads each of these stems,
locates all the archived files matching the stem, sorts them in reverse order
(i.e. most recent package first) and deletes all but the first one. It does
this by running sudo rm -v via xargs
The -p option prompts before executing the command
and -r doesn't execute if the argument list is empty (i.e. nothing
to delete).
find. Over to you!
- 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_MAXto find out what it is). We shouldn't rely on this.