I'd like to get a list of packages installed manually by apt
or aptitude
and be able to find out whether a foobar
package was installed manually or automatically.
How can we do that from the command line?
I'd like to get a list of packages installed manually by apt
or aptitude
and be able to find out whether a foobar
package was installed manually or automatically.
How can we do that from the command line?
You can use either of these two one-liners. Both yield the exact same output on my machine and are more precise than all solutions proposed up until now (July 6, 2014) in this question.
Using apt-mark
:
comm -23 <(apt-mark showmanual | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)
Using aptitude
:
comm -23 <(aptitude search '~i !~M' -F '%p' | sed "s/ *$//" | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)
Very few packages still fall through the cracks, although I suspect these are actually installed by the user, either right after the installation through the language localization setup or e.g. through the Totem codec installer. Also, the linux-header versions also seem to accumulate, even though I've only installed the non version-specific metapackage. Examples:
libreoffice-help-en-gb
openoffice.org-hyphenation
gstreamer0.10-fluendo-mp3
linux-headers-3.13.0-29
How does it work:
sed
strips out remaining whitespace at the end of the line.Other possibilities don't work as well:
ubuntu-14.04-desktop-amd64.manifest
file (here for Ubuntu 14.04) instead of /var/log/installer/initial-status.gz
. More packages are shown as manually installed even though they are not.apt-mark showauto
instead of /var/log/installer/initial-status.gz
. apt-mark
for example doesn't include the xserver-xorg package, while the other file does.I used various other StackExchange posts as references, however none work as well as the above solution:
Both list more packages than the above solution.
EDIT: What to do if you've upgraded from a previous release:
If you've upgraded Ubuntu from one release to the next, you will probably need to adjust this process. In that case, I would check the manifest file of the newer release (see above) in addition to the initial-status.gz file from the current release. You can easily do that by just adding another comparison. Using just the manifest file will not work, as the manifest file unfortunately does not contain everything that the initial_status.gz file does (I checked).
/var/log/installer/initial-status.gz
is missing. Also I want to know if this is depending on apts marking of manual
or not?
– Anwar
Oct 29 '16 at 08:20
showmanual
command (below). And use comm
to compare the two(sorted) lists. The showmanual
result gave me 1,840 more unique packages from apt-mark showmanual
not shown by this method. NO packages were unique to the output of this comm
-command. I think it is more interesting to record that for my PC, 894 packages are listed in Both results. Not sure why there's such a Vast discrepancy. Some (many?) packages seem to be release specific. Others like XOrg, GTK components and lib*
things could be updates. Anyway this answer is a very good start.
– will
Jun 24 '18 at 12:45
apt-mark showmanual
. It's interesting how many differences are visible. your list has 238 packages while showmanual returns 1717 packages. Of the 2179 installed packages, there are only 223 in both lists, 15 are only in yours (examples: nodejs, lightdm) and 223 are only in showmanual (examples: xserver-xorg, ubuntu-desktop). It feels like your list is more helpful, but without knowing where these differences come from, it's not easy to decide... (but I'm quite sure I installed nginx and lightdm manually...) [sorry will that I just wrote the same ;)]
– Daniel Alder
Sep 13 '18 at 08:45
zenity
), 2) Things I've heard of but consider core functionality (like acpi-support
), 3) stuff that's 100% useless to me (like ten printer-driver-xxx
while I don't even have a printer) and 4) stuff that's almost surely installed by another app and not by me (like thunderbird-locale-en
)
– Mark Jeronimus
Jan 26 '20 at 14:28
apt install git-review
, only git-review
gets listed. So far, so good. When I apt remove git-review
, the package git stays but is not listed. That is because git is a ‘suggests’ in the package libdpkg-perl (see /var/lib/dpkg/status). The same happens for if a package was installed with apt install --no-install recommends
and later another package installs that recommendation, then it stays but gets not listed. No idea how to catch those.
– Alexander Traud
May 11 '21 at 09:57
comm -23 <(apt-mark showmanual | sort -u) <(cat ~/Desktop/ubuntu-20.04.2.0-desktop-amd64.manifest | awk '{print $1}' | sort -u)
. Thanks!
– bmaupin
Aug 03 '21 at 19:59
git-review
was the package you installed manually. git
was not, be it a suggestion or a dependency.
– MestreLion
Nov 29 '21 at 00:04
*-locale-*
when fiddling with the Language support GUI). They can't be marked as auto or apt autoremove
would remove them, so your DE installs them as manual
– MestreLion
Nov 29 '21 at 02:13
apt-list-manual
function in ~/.bash_aliases
, also handling downloaded manifests as suggested by @bmaupin
– MestreLion
Nov 29 '21 at 04:30
git-review
is still installed, I do not need to list git
, yes. However, when I remove git-review
, I want to know that there are left-over packages, in that case git
. In this case git
is still marked installed automatically although it is just a Suggests. There is more than one package which keeps git
installed. Example use-case: I use an application, do not want to use it anymore and get rid of everything installed for it. Now, one can argue that this is not the initial question. However, such transitions might be not known while the question was phrased.
– Alexander Traud
Nov 30 '21 at 09:33
git
among manually installed packages would be useful. If no one else suggests or depends on it, apt autoremove
can take care of it.
– MestreLion
Nov 30 '21 at 17:51
mapfile -t mypackages < <(this answer); sudo apt purge "${mypackages[@]}" && sudo apt autoremove
– MestreLion
Nov 30 '21 at 17:58
Installed by another application
... Installed by [my] Desktop Environment
. Yep, installed by another application (DE) and not by me (using apt).
– Mark Jeronimus
Dec 01 '21 at 16:31
autoremove
does not take care in my case because git is a Suggests of a totally different, a default installed package. ,Consequently, when anything installs git as side effect, git ‘sticks’ on my system. Consequently, my use-case is about about those packages which are listed at ‘The following NEW packages will be installed’: git-review git git-man liberror-perl. I consider those manual installed. Apt considers only git-review installed manually. Which is fine while installing and having. However, git stays installed and stays marked ‘auto’, even when I remove git-review.
– Alexander Traud
Dec 02 '21 at 08:49
apt
is doing the right thing: git-review
is indeed the only package you requested to install, the others were pulled automatically as dependencies/suggestions. To mark git
as manual, as you consider it, means nothing would be ever marked as automatic, and the whole point of auto
/manual
would be completely moot. git
only stayed because someone else now requires/suggests it, but it's still an automatically installed package. You never directly requested it.
– MestreLion
Dec 02 '21 at 20:06
autoremove
does take care in your case, by removing any "unneeded" packages that were not directly requested by you. git
is just not unneeded anymore, someone else now requires/suggests it, so autoremove
should not remove it. It's still auto
as it should be, and "eligible" to autoremove if and when no one else depends on ti
– MestreLion
Dec 02 '21 at 20:09
In newer versions of the package apt, there is also the apt-mark command
apt-mark showmanual
linux-image-3.11.0-*-generic
etc as manual
– Daniel Alder
Jul 08 '14 at 11:23
linux-image-3.13.0-24-generic
is manual but the current linux-image-3.13.0-27-generic
is automatic. It seems that an upgrade of a referencing package (in this case linux-image-generic
, which changed the dependencies), the manual mark is automatically set
– Daniel Alder
Jul 08 '14 at 11:42
apt-get autoremove
. This is definitely not what you want.
– Anton K
Dec 02 '16 at 10:57
ubuntu-minimal
and ubuntu-standard
packages, there's no need for any of their dependencies to be marked as manual
– OrangeDog
Jun 15 '21 at 13:29
To get a list of all packages (not installed, installed by user or installed by default, across all PPAs), apt
employs the following method:
apt list [option]
The possible options useful for this are:
--installed
to display only the packages that are installed on the system (out of some 50,000+)
--manual-installed
to list the packages that were explicitly installed by a command, either directly, or as dependencies.
Alternatively, you could do:
apt list --installed | grep -F \[installed\]
to get a list of packages that resulted from user commands and their dependencies only, and to get additional information on them such as version and architecture supported (x86, x86_64, amd64, all, etc.)
apt install ...
.
– Elliott Slaughter
Apr 28 '23 at 20:56
For Ubuntu 16.04, check out the log file /var/log/apt/history.log
.
For example:
zgrep 'Commandline: apt' /var/log/apt/history.log /var/log/apt/history.log.*.gz
It's not perfect, but it's pretty good at making it clear exactly what I installed by hand. Put a -B 1
on the grep to see when it was installed.
Example output
Commandline: apt install postgresql-9.5-plv8
Commandline: aptdaemon role='role-install-file' sender=':1.85'
Commandline: apt install task
Commandline: apt autoremove
Commandline: apt install atom
Commandline: apt upgrade
Commandline: apt-get install asciinema
Commandline: apt install iperf3
Commandline: apt upgrade
Commandline: apt-get install chromium-browser
Commandline: apt install joe cpanminus build-essential postgresql libdbd-pg-perl libcrypt-openssl-bignum-perl libcrypt-openssl-rsa-perl libio-socket-ssl-perl libnet-ssleay-perl libssl-dev
Commandline: aptdaemon role='role-commit-packages' sender=':1.2314'
Commandline: apt install git
Commandline: apt install sqlite
Commandline: apt install whois
Commandline: apt install libdbd-pg-perl
Commandline: apt install perl-doc
Commandline: apt upgrade
Not sure if this picks up aptitude
or not. It doesn't seem to pick up installs from the Ubuntu Software desktop app.
comm -23 <(zgrep "Commandline: \(apt\|apt-get\) install" /var/log/apt/history.log* | sed -n 's/^Commandline: \(apt\|apt-get\) install //p' | tr " " "\n" | sort -u) <(zgrep "Commandline: \(apt\|apt-get\) \(remove\|purge\)" /var/log/apt/history.log* | sed -n 's/^Comma ndline: \(apt\|apt-get\) \(remove\|purge\) //p' | tr " " "\n" | sort -u)
– jmiserez
Aug 10 '22 at 11:23
/etc/logrotate.d/apt
to change this retention period.
– Nick ODell
Dec 05 '23 at 18:58
apt-mark showauto | grep -iE '^foobar$'
will output "foobar" if the package was installed automatically, nothing otherwise.
aptitude search '!~M ~i'
will list the packages that were not installed automatically. It's a pity aptitude won't be part of the default install on Ubuntu Desktop starting from 10.10.
aptitude search
shows ALL packages not just the ones that are manually installed (I assume that's what the OP wanted)
– Oli
Aug 16 '10 at 17:42
aptitude search '!~M ~i'
and it lists 1043 packages. There is no way I installed that many packages manually.
– ThatGraemeGuy
Sep 16 '10 at 07:42
aptitude search '!~M ~i'
shows exactly 1583 lines, many more than also I expected. But so does apt-mark showmanual
, so at least they agree.
– Peter V. Mørch
Feb 13 '13 at 08:56
I would like to give a GUI solution.
Open Synaptic Package Manager.
Go to Status.
Click Installed (manual).
It will give the list of packages installed manually by apt
or aptitude
.
Unfortunately I could not find any option in Custom Filters to find out whether a foobar
package was installed manually or automatically.
If the package is under Installed but not under Installed (manual), then it was installed automatically. If the package is under Installed (manual), then it was installed manually.
The following script will print out all the packages that are not set to automatic install and hence were installed manually:
#!/usr/bin/python
try:
import apt_pkg
except ImportError:
print("Error importing apt_pkg, is python-apt installed?")
sys.exit(1)
apt_pkg.init()
STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
auto = set()
tagfile = apt_pkg.TagFile(open(STATE_FILE))
while tagfile.step():
pkgname = tagfile.section.get("Package")
autoInst = tagfile.section.get("Auto-Installed")
if not int(autoInst):
auto.add(pkgname)
print("\n".join(sorted(auto)))
it is based on how apt-mark prints out the automatically installed packages.
sys.exit(1)
without import sys
might result in an error in newer versions of python. Either import sys
or use exit(1)
.
– Videonauth
Nov 26 '17 at 14:40
As several people have commented, apt-mark showmanual seems to be a bit buggy (and I reported it as bug 727799). When I'm using it, it actually reports a lot of stuff that isn't even logged in /var/lib/apt/extended_states (where this is supposed to be stored) and apt-get isn't logging things as installed in /var/lib/apt/extended_states (just in /var/lib/dpkg/status). The python script by txwikinger above draws from /var/lib/apt/extended_states directly but if you're using it today the syntax might not work (mine just started generating errors with Kubuntu 13.10). Updated syntax is:
#!/usr/bin/python
import sys
try:
import apt_pkg
except ImportError:
print "Error importing apt_pkg, is python-apt installed?"
sys.exit(1)
apt_pkg.init()
STATE_FILE = apt_pkg.config.find_dir("Dir::State") + "extended_states"
auto = set()
tagfile = apt_pkg.TagFile(open(STATE_FILE))
while tagfile.step():
pkgname = tagfile.section.get("Package")
autoInst = tagfile.section.get("Auto-Installed")
if not int(autoInst):
auto.add(pkgname)
print "\n".join(sorted(auto))
For me this was a very short list of 5 items which doesn't seem to be accurate either.
sys.exit(1)
without import sys
might result in an error in newer versions of python. Either import sys
or use exit(1)
.
– Videonauth
Nov 26 '17 at 14:40
If you're in a VM (Virtual Machine), then the following might work better for you:
egrep 'apt(-get)? +install' /var/log/apt/history.log
That finds software you installed both via apt
and apt-get
. If you'd like to include aptitude
too, this should work:
egrep 'apt(-get|itude)? +install' /var/log/apt/history.log
(But don't think this'd find packages installed directly via dpkg
— which I don't really do anyway.)
Rationale: If the Virtual Machine already included some default software installed by the VM maintainers (in the base image), but not by you, then, this answer won't show the software they installed (well at least not in the VMs I'm using), only the software you installed.
The other answers here, which uses e.g. apt-mark showmanual
or aptitude search '!~M ~i'
or apt list --manual-installed
, in my case, in a VM, showed 90% to me uninteresting packages that I didn't install — instead, some of the VM base image maintainers did (I presume).
An updated version of @jmiserez' answer:
comm -23 \
<(apt-mark showmanual | sort -u) \
<(grep -oP '^(?:Package|Depends):\s+\K.*' /var/log/installer/status \
| grep -oP '[^\s,()]+?(?=(?:\s+\([^)]+\))?+(?:,|$))' \
| sort -u)
The log is no longer stored at /var/log/installer/initial-status.gz
and the original did not omit dependent packages. The list it produces will include packages you didn't manually install, but it's a more manageable length and still very useful.
Compiled from the awesome answers by others in this thread and additional info from the internet I assembled a command that fits my needs and perfectly replicates my apt history:
ls /var/log/apt/history.log* | sort --version-sort | xargs -d '\n' zgrep -B 1 'Commandline: apt'
So, first of all, it outputs history in chronological order, e.g.
/var/log/apt/history.log.1
/var/log/apt/history.log.2
...
/var/log/apt/history.log.10
You can add --reverse
param to the sort to sort files in reverse order. That way you'll have oldest commands on the top of the list.
Plus it has date of the command.
Kudos to @s1037989 and @iruvar
If no one gives you a nice answer using a apr-something command you can do it the hard way. Apt-get stores its info in /var/lib/apt/extended_states. Any file that is installed automatically will be added to this file. If you install a package already in this file manually, the package will remain in this file but with Auto-installed: 0 in the second line. It's not deleted.
Note: As expected better answers that are likely to work if file placement changes have appeared. I keep mine just in case the info on the file location is useful.
apt-get install liferea
and it didn't install but I got output that was something to the effect of "marked as manually installed". Now liferea is still in the file, except the next line has a 0
instead of a 1
. Also, you should change your regex pattern to " foobar$"
instead of just foobar
.
– Umang
Aug 17 '10 at 13:21
After googling a lot, I've managed to assemble this script. It works alright for me:
#!/bin/bash
List of all packages currently installed
current=$(dpkg -l | awk '{print $2}' | sort | uniq)
List of all packages that were installed with the system
pre=$(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort | uniq)
List of packages that don't depend on any other package
manual=$(apt-mark showmanual | sort | uniq)
(Current - Pre) ∩ (Manual)
packages=$(comm -12 <(comm -23 <(echo "$current") <(echo "$pre")) <(echo "$manual") )
for pack in $packages; do
packname=$(echo $pack | cut -f 1 -d ":")
desc=$(apt-cache search "^$packname$" | sed -E 's/.* - (.*)/\1/')
date=$(date -r /var/lib/dpkg/info/$pack.list)
echo "# $desc"
echo "# $date"
echo "sudo apt-get install $pack"
echo -e ""
done
sort -u
instead of sort | unique
. As apt-mark
does not display architecture, you should strip it from dpkg's output before the set operations (or use dpkg-query -W -f='${Package}\n'
). Besides, dpkg may list some packages that are not installed currently. As for "desc", you could use `dpkg-query -W -f='# ${binary:Summary}\n' $pack, which is faster.
– jarno
Dec 20 '15 at 15:54
apt-mark
may display architecture for some packages, but not for so many as dpkg -l
.
– jarno
Dec 20 '15 at 23:47
apt-cache search
is slow. Getting a list of installed dates in advance using something like https://help.ubuntu.com/community/ListInstalledPackagesByDate might be more efficient
– opticyclic
Aug 24 '17 at 03:37
This gets you a list of manual installed packages and its corresponding version
apt list --manual-installed | sed 's/\// /' | awk '{print $1 "=" $3}'
As Li Lo said, apt-mark showauto
should get you a fat list of things automatically installed.
Now to show the things that are installed manually, it turns out there's a lovely simple search modifier for aptitude. But you don't want to to do that. You want to write a huge bash command that does some rocket science.
Note: This is more an illustration of how cool you'll look busting out massive bash commands to all your friends.
comm -3 <(dpkg-query --show -f '${Package} ${Status}\n' | \n
grep "install ok installed" | cut --delimiter=' ' -f 1) <(apt-mark showauto)
I broke it onto two lines for readability. What does this do?
apt-mark
comm -3 <(dpkg -l | grep '^ii' | cut -d \ -f 3|sort) <(apt-mark showauto|sort)
is properly better ;)
– LasseLuttermann
Aug 16 '10 at 17:54
Not sure if this is helpful, but to find packages that were recently installed manually by the current user, search the history. E.g., for bash
:
$ history | egrep '\bapt\b'
Modify the grep to check for specific packages.
If you installed all your packages from the terminal using apt, you could throw a simple regex searching for apt install *
at the contents of /var/log/apt/history.log
and see what it gobbles up.
The regex might be as simple as: Commandline: apt install [\w -]+
(following the log syntax of apt on Ubuntu 16.04)
From Ubuntu 22.04 and onwards, you could take care of this using a more modern apt
front-end called nala
(for 22.04 you have to enable the "universe" repository).
sudo apt install nala
From this point, use nala
to install new packages on your system, using:
sudo nala install <package-name>
Leave security updates etc. to the unattended-upgrades
package.
Now, when you run the command nala history
, you get a list of the commands run with nala, including installed packages. To filter only new installations, use:
nala history | grep install
An added bonus of the history feature is that you can undo any step in the history, so that you can reverse package installation procedures - something that is unnecessarily hard using apt
itself.
I have found an elegant method for doing this.
Just output the ~/.bash_history
file with the grep
command to sort them out:
cat .bash_history | grep "apt install"
Conveniently, you can look out for an apt-get
too.
An example output, I have:
sudo apt install -f
sudo apt install vim
sudo apt install dconf
sudo apt install dconf-editors
sudo apt install dconf-editor
sudo apt install nmap
sudo apt install python-tk
sudo apt install python-tk
This will list all manually installed packages without: dependencies, uninstalled packages, packages installed during system installation.
unopts() {
in=`cat`
echo "$in" | sed -r 's/ --[^ ]+//g;s/ -[^ ]+//g'
}
list() {
cat '/var/log/apt/history.log' |
grep --color=never -v '\-o APT::Status-Fd=4 \-o APT::Keep-Fds::=5 \-o APT::Keep-Fds::=6' |
egrep --color=never "Commandline: apt-get.* $1" |
sed -r "s/Commandline: apt-get//;s/ $1//" |
unopts |
tr ' ' '\n' |
sed '/^$/d'
}
hapt() {
tmp=`mktemp -d`
installed=$tmp/installed
deleted=$tmp/deleted
dpkg=$tmp/dpkg
list 'install' > $installed
list '(remove|purge|autoremove)' > $deleted
dpkg --get-selections |
grep -v 'deinstall' |
cut -f 1 > $dpkg
while read package
do
sed -i "0,/$package/{//d;}" $installed
done < $deleted
while read package
do
if [ -z "`grep --color=never "^$package$" $dpkg`" ]
then
sed -i "0,/$package/{//d;}" $installed
fi
done < $installed
cat $installed
rm -r $tmp
}