Sunday, July 26, 2009

List all installed applications

There are times in a person's life when they just gotta get that brand new Ubuntu put on their computer.

For me, that inadvertently means trying to figure out what applications I forgot to install this time. Knowing life I'll be on a train somewhere, and remember that I had to do this important presentation that I forgot about and I'll have no beamer installed, or some similar situation.

So, I've been thinking that maybe I could move the list of stuff I installed on one computer to another. However, for various reasons (including technical ones) I don't want a list of all packages that are actually installed on the system - just the apps.

I figured that the gnome Add/Remove Applications thing (gnome-app-install) actually filters out a lot of the packages, and only leaves in the applications, so I took a look at how they do it, and it turns out that there are files in the system (in /usr/share/app-install/desktop), that could provide me with all the information. So I had what I needed at this juncture.

Now, what this thing does is, it goes to that directory, opens all 2000 or so .desktop files (one per application), reads the property defining what package you need to install (X-AppInstall-Package) and finally check with dpkg if that package is installed on the system, and Bob's your uncle!

Two drawbacks: (a) it's a bit slow and (b) it returns duplicate packages. I don't intend to think about fixing them because, (a) you're not gonna run this script much more often than about twice a year, so you can bloody wait 10 minutes; and (b) there are other commands to do that, and it's not like there's a lot of those duplicates anyway.

So, here's how I propose it can be used. Before installing a new version of the distro, run:
./lsapp | sort -u > applications.list

Then you can copy that file in some safe place, like a pendrive, or the partition you're not planning on wiping.

When you got your new version of the distro installed, you can copy that list somewhere and go:
cat applications.list | xargs echo | xargs sudo apt-get install

and all your stuff should attempt to be installed.

And Bob is, now and forever, your uncle.

Let me just add, that this should work for Ubuntu, but I didn't actually research if other distros store the application information in a similar manner. Hopefully, they do. I figure it's probably necessary to have gnome-app-install on there somewhere though.

Here's the code.
 
1 #!/bin/bash
2 #
3 # lsapp
4 #
5 # A simple script to list applications installed on the system.
6 #
7 # An application is simply a package that is refered to in a .desktop
8 # by the property "X-AppInstall-Package". These files are located in
9 # /usr/share/app-install/desktop.
10 #
11 # The script may take some time to run, and does not remove duplicate
12 # entries.
13 #
14 # Requires:
15 # dpkg
16 # gnome-app-install
17 # Author:
18 # Konrad Siek <konrad.siek@gmail.com>
19 #
20 # License information:
21 #
22 # This program is free software: you can redistribute it and/or modify
23 # it under the terms of the GNU General Public License as published by
24 # the Free Software Foundation, either version 3 of the License, or
25 # (at your option) any later version.
26 #
27 # This program is distributed in the hope that it will be useful,
28 # but WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 # GNU General Public License for more details.
31 #
32 # You should have received a copy of the GNU General Public License
33 # along with this program. If not, see <http://www.gnu.org/licenses/>.
34 #
35 # Copyright 2009 Konrad Siek
36
37 # Directory containing .desktop files.
38 DESKTOP_DIR=/usr/share/app-install/desktop
39
40 # The property in .desktop files that gives you the actual package name.
41 PROPERTY=X-AppInstall-Package
42
43 # Iterate over all the files in that directory.
44 find "$DESKTOP_DIR" -type f | while read file
45 do
46 # Get package name from the desktop file.
47 package=`tac "$file" | \
48 awk -F '=' -v key="$PROPERTY" '$1 == key {print $2; exit}'`
49
50 # No package found, go to next file.
51 if [ -z "$package" ]
52 then
53 continue
54 fi
55
56 # Check if a package is installed.
57 dpkg -s "$package" > /dev/null 2> /dev/null
58 if [ $? == 0 ]
59 then
60 # If so, print out the name.
61 echo "$package"
62 fi
63 done


The code is also available at GitHub as bash/lsapp.

No comments: