How to get a list of manually installed packages (and remove the other ones)

The Good

Every other year or so I feel the need to clean up my Debian system and remove the installed packages I’m not interested in anymore. I remember there was a nice aptitude pattern to search for packages which I have manually installed (i.e. which were not installed to satisfy a dependency). Ideally I would then go through the (presumably short) list of packages and remove the ones I don’t need any more.

Since I always forget the aptitude pattern to search for those packages, I google for something like “list of manually installed packages” and find a solution like: aptitude search ‘~i !~M’. Although this solution is not wrong, it is not quite what I was looking for. Sure, it will find you all packages which are installed and not installed to satisfy a dependency, but it also contains packages of priorities: required, important and standard which you usually don’t want to deinstall. So the actual solution should also exclude those packages.

aptitude search '~i !~M !~pstandard !~pimportant !~prequired'

The above line will do the trick and present you a list of packages which are: installed and not dragged in to satisfy a dependency and not of priority standard, important or required.

If you where only interested in the solution of the quest of getting a list of all manually installed packages you can stop reading here.

The Bad

If you’re running your system for longer than, say, a few weeks you will probably notice that the list is very long and contains much more packages than you actually installed manually. You will probably notice a lot of libs and other packages in this list and wonder why they aren’t marked auto as they should since you didn’t install them on purpose. Unfortunately I don’t have an answer for that question. I’m using aptitude exclusively to install packages and rely on the fact that aptitude does install the dependencies automatically and more importantly: also removes them if not needed any more. But it seems like something is broken in aptitude (or somewhere else) and packages simply lose their auto status instead of being removed and thus stay on your system forever if you don’t manually clean your system.

The Ugly

To solve that issue I started aptitude and filtered the package tree with the above pattern (press l in aptitude and enter ~i !~M !~pstandard !~pimportant !~prequired). Now the package view shows only packages which are safe to remove since they are not of of priority standard or higher and manually installed by you. Now I navigate with the cursor to the list of installed packages an mark all of them as auto by pressing M. For each package in this list, aptitude will try to find an installed package which depends on that package and mark that package auto. The remaining packages which no other packages depend on, aptitude will mark for deletion. If you now press g one time, aptitude will show you which packages will be removed. I then go through that list and mark every single of the remaining packages I really want on my system with + as manually installed. After I’m done I proceed by pressing g again which will remove all remaining packages. In my case nearly 600 packages (1GB) where removed.

Bugreport!

I assume there is a bug in aptitude or some related package which sometimes(!) removes a packages auto status instead of removing it. Unfortunately I did not find a way to reproduce that (except that it obviously does happen). If someone could find a way to reproduce that problem, one could fill a bugreport and help to get that bug fixed. Right now, a Debian system suffers (like many other operating systems) from a slow but steadily growing bloat of installed software. In my case 600 packages with 1GB accumulated over one or two years.

8 thoughts on “How to get a list of manually installed packages (and remove the other ones)

  1. Stefan

    I think pressing “+” on “Upgradable Packages” sometimes marks auto-installed as manually installed (afaik it behaves like a “foreach p in list: {upgrade(p), resolve conflicts}”)
    “Mark Upgradable” (shortcut “shift-U”) is the better one, and keeps “hold” marks intact.

  2. Lachlan

    If you apt-get a package thats already installed it removes auto status.
    I’m not sure if aptitude does the same.

    Also I really needed that aptitude command! :) I’m testing out multi arch today.

  3. Anonymous

    I’d suggest something like this instead:

    ?installed ?not(?automatic) ?reverse-Depends(?installed)

    That’ll show you all non-automatic packages depended on by other things you have installed. You want to mark most of those as automatic.

  4. Anonyme

    I noted that aptitude removes the M(anual) tag on some packages when there are conflicts and part of the solution is to not upgrade them.

    It happened for a all bunch of libs in july/september in Sid: libsmoke* waiting for qtruby to be updated.

    As it is applying (with ‘!’) the chosen solution that removes the tag, I suspect the conflict management to be (a) culprit .

  5. choper

    Thousands and thousands of persons want to have a list of the packages they have manually . explicitly given the order to install. It is hard time somebody did something about this instead of so much changing the desktop appearance so that the screenshots and videos sell well.

  6. mmm4m5m

    Thanks for the help! Below is my way – glad if that helps you back :)

    ### Hint: packages installed by default = packages with priorities: required important standard.
    ### Hint: custom installed packages = packages with priorities: optional extra
    ### Some of default packages are marked as "essential" - you can't remove these.

    ### create the report
    aptitude -s search '!~pRequired !~pImportant !~pStandard !~pOptional !~pExtra' | grep -v '^v ' | sed -e 's/^/VIR /' > packages-virtual
    aptitude -s search '~E' | sed -e 's/^/ESS /' > packages-status &&
    aptitude -s search '~pRequired !~E' | sed -e 's/^/req /' >> packages-status &&
    aptitude -s search '~pImportant !~E' | sed -e 's/^/imp /' >> packages-status &&
    aptitude -s search '~pStandard !~E' | sed -e 's/^/sta /' >> packages-status &&
    aptitude -s search '~pOptional !~E' | grep -v '^p ' | sed -e 's/^/opt /' >> packages-status &&
    aptitude -s search '~pExtra !~E' | grep -v '^p ' | sed -e 's/^/ext /' >> packages-status

    ### check 1: all default packages must be installed
    cat packages-status | grep "^... [^i].. " | sed -e "s/^... ... //" -e "s/ .*$//"

    ### re-create the report!
    ### step 1: packages installed by default: mark as auto
    apt-mark auto `cat packages-status | grep "^\(ESS\|req\|imp\|sta\) i.[^A] " | sed -e "s/^... ... //" -e "s/ .*$//"`

    ### re-create the report!
    ### step 2: packages installed by default: if autoremove then mark as manual
    apt-mark manual `cat packages-status | grep "^\(ESS\|req\|imp\|sta\) idA " | sed -e "s/^... ... //" -e "s/ .*$//"`

    ### check 2: never autoremove default packages
    cat packages-status | grep "^\(ESS\|req\|imp\|sta\) id. " | sed -e "s/^... ... //" -e "s/ .*$//"

    ### restore 'manual' marks from old report - for all custom packages (not default)
    apt-mark manual `cat packages-status | grep "^\(opt\|ext\) i.[^A] " | sed -e "s/^... ... //" -e "s/ .*$//"`

Comments are closed.