Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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. Is there any neat way of doing that from the command line?

share|improve this question
See this answer on for a solution that filters out stock packages. – Dirk Bergstrom Apr 19 '12 at 16:57
Possible duplicate? - – James Apr 28 '12 at 19:03
Really good solution that excludes packages installed by default: Ubuntu list explicitly installed packages – pcworld Nov 30 '13 at 18:51
up vote 57 down vote accepted

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:


How does it work:

  1. Get the list of manually installed packages. For aptitude, the additional sed strips out remaining whitespace at the end of the line.
  2. Get the list of packages installed right after a fresh install.
  3. Compare the files, only output the lines in file 1 that are not present in file 2.

Other possibilities don't work as well:

  • Using the 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.
  • Using 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).

share|improve this answer
This really does look like the closest to a real solution. Thank you. – Umang Jul 7 '14 at 11:07

In newer versions of the package apt, there is also the apt-mark command

apt-mark showmanual
share|improve this answer
Exactly the answer I was searching for. – Wolfer Oct 30 '13 at 19:18
This shows way more packages than I have installed manually. – Umang Jul 7 '14 at 11:05
@Umang You are right. I would say this wasn't like this when I wrote this answer. There is no reason on my system to consider linux-image-3.11.0-*-generic etc as manual – Daniel Alder Jul 8 '14 at 11:23
@Umang maybe this will help you…, but the answer is not accepted. Fact is, that many packages of a fresh installation are already marked as manual. But there are still some strange things. To stay with my example: 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 8 '14 at 11:42

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.

share|improve this answer
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
@Oli: look into aptitude search patterns; the pattern I'm using there should do exactly what the OP wants. – Li Lo Aug 16 '10 at 17:44
I ran it. It shows a whole load of packages that aren't installed. – Oli Aug 16 '10 at 17:46
My bad. Corrected. Thank you. – Li Lo Aug 16 '10 at 17:50
Something isn't right with this, I'm using aptitude search '!~M ~i' and it lists 1043 packages. There is no way I installed that many packages manually. – ThatGraemeGuy Sep 16 '10 at 7:42

The following script will print out all the packages that are not set to automatic install and hence were installed manually:


    import apt_pkg
except ImportError:
    print "Error importing apt_pkg, is python-apt installed?"

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):
print "\n".join(sorted(auto))

it is based on how apt-mark prints out the automatically installed packages.

share|improve this answer
Kudos to you fine sir. This actually works, in contrast to the accepted answer. – Irfy Nov 1 '12 at 2:53
show just a couple of package for me --- definitely missing a lot of them. – Rmano Jan 23 '14 at 17:36
Same here, definitely missing manually installed packages, right after I installed them. – David Ljung Madison Mar 2 at 1:23

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:


    import apt_pkg
except ImportError:
    print "Error importing apt_pkg, is python-apt installed?"

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):
print "\n".join(sorted(auto))

For me this was a very short list of 5 items which doesn't seem to be accurate either.

share|improve this answer

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?

  • First we query dpkg for a list of packages that are installed.
  • We filter those for the ones that are actually installed (not just residual config)
  • We chop off the status
  • We compare that list with the automated list from apt-mark
  • We rock out because we can.
share|improve this answer
I doubt this is accurate, since dpkg often shows packages that are not installed – txwikinger Aug 16 '10 at 17:47
I know what you mean but my bash-fu isn't strong enough. I know you could show the status from dpkg-query, grep that down and then slice off the status. I'll have a go. – Oli Aug 16 '10 at 17:49
comm -3 <(dpkg -l | grep '^ii' | cut -d \ -f 3|sort) <(apt-mark showauto|sort) is properly better ;) – LassePoulsen Aug 16 '10 at 17:54

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.

share|improve this answer
No. I took a quick look at that file to find that liferea was marked as auto-installed. I did an 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
That's true. My fault, in my system there is no line with 0, but it should be a rare happening. I update the answer just in case. – Javier Rivera Aug 17 '10 at 16:14

After googling a lot, I've managed to assemble this script. It works alright for me:

# 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 ""
share|improve this answer
You could use sort -u instead of sort | unique. As apt-markdoes 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
Oh, apt-markmay display architecture for some packages, but not for so many as dpkg -l. – jarno Dec 20 '15 at 23:47

This will list all manually installed packages without: dependencies, uninstalled packages, packages installed during system installation.

unopts() {
  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`
  list 'install' > $installed
  list '(remove|purge|autoremove)' > $deleted
  dpkg --get-selections |
  grep -v 'deinstall' |
  cut -f 1 > $dpkg
  while read package
    sed -i "0,/$package/{//d;}" $installed
  done < $deleted
  while read package
    if [ -z "`grep --color=never "^$package$" $dpkg`" ]
      sed -i "0,/$package/{//d;}" $installed
  done < $installed
  cat $installed
  rm -r $tmp
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.