views:

71

answers:

3

Is there a way of getting dpkg, apt-get or aptitude to produce a list of the packages which need to be installed on a second machine to duplicate the packages installed on a first?

i.e. If I've installed a plain Ubuntu server, chose the sshd option at install time, then installed build-essential I would expect the output to look something like:

#ubuntu 9.10 server
openssh-sshd
build-essential

As far as I can see, all the available packaging tools will produce a verbose list of the packages on a box. I'm not interested in openssh libs, ld, gcc, and all the other packages pulled in by sshd and build-essential, as they will be installed when I install sshd and build-essential.

I would like to see just the list of the package which I need to install to recreate my current set of packages on another machine.

Is this possible?

A: 

So, you want the list of packages which were explicitly installed (like, say, ubuntu-desktop and openssh), and not the auto-dependencies? I'm not positive, but I think that's what dpkg --get-selections does. So, you can do

dpkg --get-selections > file

And then, on the other computer, use the same "file" and run

dpkg --set-selections  < file
apt-get dselect-upgrade

I'm not absolutely positive that those commands just do manually selected packages, though, and I'm currently away from any Debian-based systems to verify on. :)

dannysauer
No, it looks like it lists packages that were pulled in as dependencies. On my machine, the list includes packages such as g++, g++-4.4, gcc... which I know were installed by build-essential.
chrisdew
+1  A: 

deborphan, sort of. It builds a list of every package in your system, figures out what depends on what, and prints out the packages that don't have any dependencies. By default it only prints libraries (to make it easy to find libraries that were installed by other packages and no longer needed, hence the name). It has options for doing what you want, mostly. I run it like:

deborphan -anp required --no-show-section

-a specifies all packages (not just libraries)
-n ignores "Suggests" or "Recommends" dependency checking (i.e. just "Depends")
-p required lists all packages despite priority
--no-show-section doesn't indicate which part of debian it's in, just a nice formatting feature you might find useful for building a list.

Now, it will miss packages, because some packages have circular dependencies. But those tend to be fairly uncommon, so it should get you close enough.

Eric Warmenhoven
Why does 'deborphan -anp required --no-show-section' include 'gcc' in it's output, when 'apt-rdepends build-essential' shows that 'build-essential' depends on 'gcc'?
chrisdew
Is it showing a specific version of gcc, like gcc-4.3, or the gcc package itself? If it's the 'gcc' package, perhaps build-essential isn't actually installed? ... no good guesses, sorry. In my output, I see build-essential but no gcc.
Eric Warmenhoven
+1  A: 

The code that dannysauer posted is a start. Once you have a list of packages that includes dependencies, you can use apt-rdepends to find the dependencies for a particular package (see this page for example usage and output).

Procedure outline

  1. Iterate through the list of packages returned by dannysauer's code
  2. Call apt-rdepends on each
  3. Delete any packages from the list that show up in the output of apt-rdepends
bta
I think this is also a workable approach, but it seems slower and more work than deborphan. Is there any problem with using deborphan that apt-rdepends solves?
chrisdew
IIRC, `deborphan` just makes a list of installed packages that have nothing that depends on them. This may not be what you want (see Eric's comment above about `deborphan` possibly missing packages). In case you have problems, I mentioned `apt-rdepends` because you can always get a full list of all installed packages off of both machines, delete packages common to both lists, and examine the remaining packages with `apt-rdepends` to generate the shortest possible list of packages that will recreate your current package set on the second machine. This should also be easily scriptable.
bta