List packages on an apt based system by installation date
RPM-based distributions like Red Hat are easy:
rpm -qa --last
On Debian and other dpkg-based distributions, your specific problem is easy too:
grep install /var/log/dpkg.log
Unless the log file has been rotated, in which case you should try:
grep install /var/log/dpkg.log /var/log/dpkg.log.1
In general, dpkg
and apt
don't seem to track the installation date, going by the lack of any such field in the dpkg-query
man page.
And eventually old /var/log/dpkg.log.*
files will be deleted by log rotation, so that way isn't guaranteed to give you the entire history of your system.
One suggestion that appears a few times (e.g. this thread) is to look at the /var/lib/dpkg/info
directory.
The files there suggest you might try something like:
ls -t /var/lib/dpkg/info/*.list | sed -e 's/\.list$//' | head -n 50
To answer your question about selections, here's a first pass.
build list of packages by dates
$ find /var/lib/dpkg/info -name "*.list" -exec stat -c $'%n\t%y' {} \; | \
sed -e 's,/var/lib/dpkg/info/,,' -e 's,\.list\t,\t,' | \
sort > ~/dpkglist.dates
build list of installed packages
$ dpkg --get-selections | sed -ne '/\tinstall$/{s/[[:space:]].*//;p}' | \
sort > ~/dpkglist.selections
join the 2 lists
$ join -1 1 -2 1 -t $'\t' ~/dpkglist.selections ~/dpkglist.dates \
> ~/dpkglist.selectiondates
For some reason it's not printing very many differences for me, so there might be a bug or an invalid assumption about what --get-selections
means.
You can obviously limit the packages either by using find . -mtime -<days>
or head -n <lines>
, and change the output format as you like, e.g.
$ find /var/lib/dpkg/info -name "*.list" -mtime -4 | \
sed -e 's,/var/lib/dpkg/info/,,' -e 's,\.list$,,' | \
sort > ~/dpkglist.recent
$ join -1 1 -2 1 -t $'\t' ~/dpkglist.selections ~/dpkglist.recent \
> ~/dpkglist.recentselections
to list only the selections that were installed (changed?) in the past 4 days.
You could probably also remove the sort
commands after verifying the sort order used by dpkg --get-selections
and make the find
command more efficient.
Mikel has shown how to do this at the dpkg level. In particular, /var/lib/dpkg/info/$packagename.list
is created when the package is installed (and not modified afterwards).
If you used the APT tools (which you presumably did since you're concerned about automatically vs manually installed packages), there's a history in /var/log/apt/history.log
. As long as it hasn't rotated away, it keeps track of all APT installations, upgrades and removals, with an annotation for packages marked as automatically installed. This is a fairly recent feature, introduced in APT 0.7.26, so in Debian it appeared in squeeze. In Ubuntu, 10.04 has history.log
but the automatically-installed annotation is not present until 10.10.
Rough, but works :
for fillo in `ls -tr /var/lib/dpkg/info/*.list` ;
do basename ${fillo} | sed 's/.list$//g' ;
done > forens.txt
ls -ltr /var/lib/dpkg/info/*.list > forentime.txt
for lint in `cat forens.txt` ; do
echo -n "[ ${lint} Installed ] : " ;
echo -n "`grep /${lint}.list forentime.txt | awk '{ print $6, $7, $8 }'` : " ;
( ( grep -A3 " ${lint}$" /var/lib/apt/extended_states | \
grep '^Auto' > /dev/null ) && echo "Auto" ) || echo "Manual" ;
done > pkgdatetime.txt