6

I would like to list the recursive dependencies of a given package, with the currently installed version of each dependency. I'd also like one entry on each line, so it's sortable and diffable.

Basically, given, say, tcpdump, I would like the output to look like:

libtext-wrapi18n-perl: 0.06-7
perl-base: 5.14.2-21+deb7u2

...etc. The exact format of each line doesn't matter so much, just the ability to diff and sort.

The question List (recursive) dependencies of the installed packages in APT is similar, but doesn't give package versions. Using debfoster -d looks promising, but its output does not lend itself to further processing.

  • I'm unclear what you want. I don't see any direct connection between tcpdump and libtext-wrapi18n-perl and perl-base. You write "recursively list a package's dependencies". Does that mean you want all the packages that "tcpdump" has a runtime dependency on? The immediate dependencies are given for example by apt-cache show tcpdump, and are Depends: libc6 (>= 2.7), libpcap0.8 (>= 1.2.1), libssl1.0.0 (>= 1.0.0). Or do you want the reverse dependencies of tcpdump, i.e. the packages that have a runtime dependency on tcpdump? This is given by apt-cache rdepends tcpdump. – Faheem Mitha Mar 9 '15 at 3:09
  • You could also check out apt-rdepends tcpdump and apt-rdepends -r tcpdump. apt-cache rdepends seems kinda flakey; you might prefer apt-rdepends. – Faheem Mitha Mar 9 '15 at 3:14
  • @FaheemMitha I want all packages that tcpdump depends upon, and all of their dependencies, and all of their dependencies, etc. – detly Mar 9 '15 at 3:18
  • 1
    @FaheemMitha FYI apt-cache rdepends shows reverse dependencies (aka. dependants). Very confusingly, it has a similar name to apt-rdepends, which shows recursive dependencies. – detly Mar 9 '15 at 3:19
  • apt-rdepends show recursive dependencies. apt-rdepends -r shows reverse recursive dependencies. Doesn't. apt-rdepends work for you then? – Faheem Mitha Mar 9 '15 at 4:22
6

Both answers already provided have their pros and cons.

Starting with debfoster gives a list of packages which is simple to parse, so the following gives the requested result:

apt-cache policy $(debfoster -q -d tcpdump|tail -n +2)|awk '/^[^ ]/ { package=$0 } /  Installed/ { print package " " $2 }'

using tail to skip the first line and awk to process the result in a single operation. (Using a command substitution avoids the need to process newlines.) Starting with debfoster means we can only do this with a package which is already installed, so we can then use dpkg to provide more information:

dpkg -l $(debfoster -q -d tcpdump|tail -n +2)

Starting with apt-rdepends gives a list of packages which is a little harder to process, with duplicates; but it has the advantage of being able to process packages which aren't yet installed:

apt-cache policy $(apt-rdepends -p tcpdump 2>| /dev/null|awk '/Depends/ {print $2}'|sort -u)|awk '/^[^ ]/ { package=$0 } /  Installed/ { print package " " $2 }'

This can also be used with dpkg -l:

dpkg -l $(apt-rdepends -p tcpdump 2>| /dev/null|awk '/Depends/ {print $2}'|sort -u)

but this requires that dpkg know about all the packages involved, which may not be the case if the package being processed isn't installed.

debfoster includes Recommends by default; this can be disabled using --option UseRecommends=no:

debfoster -q --option UseRecommends=no -d tcpdump

apt-rdepends doesn't include Recommends by default; this can be enabled using -f Depends,PreDepends,Recommends -s Depends,PreDepends,Recommends:

apt-rdepends -f Depends,PreDepends,Recommends -s Depends,PreDepends,Recommends -p tcpdump

although it doesn't give all the dependencies debfoster finds in that case. (For example debfoster finds that tcpdump depends on apt via libssl1.0.0, debconf and apt-utils, but apt-rdepends doesn't.)

  • Nice, I didn't know about that tail option! In my situation, I only care about installed packages, but the solutions for not-installed packages might prove useful too. – detly Mar 10 '15 at 20:03
2

The following set of commands seems to do it:

debfoster -q -d tcpdump |
 sed -n '1!p' |
 tr -s ' ' |
 xargs |
 tr '\n' ' ' |
 xargs -I _ -d ' ' -n 1 sh -c "echo  _: \"\$(apt-cache policy _ | grep '  Installed: ' | sed -e 's/  Installed: //')\""

This uses:

  • debfoster to print the (recursive) dependencies
  • sed to remove the first line
  • tr to collapse extra spaces
  • xargs to trim leading and trailing space
  • tr to remove the trailing newline
  • xargs to:
    • echo the package name
    • use apt-cache policy to find the installed version (along with grep and sed to extract the version itself.

It produces:

apt-utils: 1.0.1ubuntu2.6
debconf: 1.5.51ubuntu2
debconf-i18n: 1.5.51ubuntu2
dpkg: 1.17.5ubuntu5.3
gcc-4.8-base: 4.8.2-19ubuntu1
[...etc...]

If anyone can see a way to simplify this, let me know.

2

The poster writes (in a comment):

I want all packages that tcpdump depends upon, and all of their dependencies, and all of their dependencies, etc.

apt-rdepends does this. NOTE: the "r" in "rdepends" means "recursive".

apt-rdepends -p tcpdump
Reading package lists... Done
Building dependency tree       
Reading state information... Done
tcpdump
  Depends: libc6 (>= 2.7) [Installed]
  Depends: libpcap0.8 (>= 1.0.0) [Installed]
  Depends: libssl0.9.8 (>= 0.9.8m-1) [NotInstalled]
libc6
  Depends: libc-bin (= 2.11.3-4) [Installed]
  Depends: libgcc1 [Installed]
libc-bin
libgcc1
  Depends: gcc-4.4-base (= 4.4.5-8) [NotInstalled]
  Depends: libc6 (>= 2.2.5) [Installed]
gcc-4.4-base
libpcap0.8
  Depends: libc6 (>= 2.7) [Installed]
libssl0.9.8
  Depends: debconf (>= 0.5) [Installed]
  Depends: debconf-2.0 [NotInstalled]
  Depends: libc6 (>= 2.7) [Installed]
  Depends: zlib1g (>= 1:1.1.4) [Installed]
debconf
  Depends: debconf-english [NotInstalled]
  Depends: debconf-i18n [Installed]
  PreDepends: perl-base (>= 5.6.1-4) [Installed]
debconf-english
  Depends: debconf [Installed]
debconf-i18n
  Depends: debconf [Installed]
  Depends: liblocale-gettext-perl [Installed]
  Depends: libtext-charwidth-perl [Installed]
  Depends: libtext-iconv-perl [Installed]
  Depends: libtext-wrapi18n-perl [Installed]
liblocale-gettext-perl
  Depends: libc6 (>= 2.2.5) [Installed]
  PreDepends: perl-base (>= 5.10.0-25) [Installed]
  PreDepends: perlapi-5.10.0 [NotInstalled]
perl-base
  PreDepends: dpkg (>= 1.14.20) [Installed]
  PreDepends: libc6 (>= 2.4) [Installed]
dpkg
  PreDepends: coreutils (>= 5.93-1) [Installed]
  PreDepends: libbz2-1.0 [Installed]
  PreDepends: libc6 (>= 2.6) [Installed]
  PreDepends: libselinux1 (>= 1.32) [Installed]
  PreDepends: xz-utils [Installed]
  PreDepends: zlib1g (>= 1:1.1.4) [Installed]
coreutils
  PreDepends: libacl1 (>= 2.2.11-1) [Installed]
  PreDepends: libattr1 (>= 2.4.41-1) [Installed]
  PreDepends: libc6 (>= 2.6) [Installed]
  PreDepends: libselinux1 (>= 1.32) [Installed]
libacl1
  Depends: libattr1 (>= 2.4.41-1) [Installed]
  Depends: libc6 (>= 2.2.5) [Installed]
libattr1
  Depends: libc6 (>= 2.2.5) [Installed]
libselinux1
  Depends: libc6 (>= 2.3.4) [Installed]
libbz2-1.0
  Depends: libc6 (>= 2.3) [Installed]
xz-utils
  Depends: libc6 (>= 2.6) [Installed]
  Depends: liblzma2 (>= 5.0.0) [NotInstalled]
liblzma2
  Depends: libc6 (>= 2.2.5) [Installed]
zlib1g
  Depends: libc6 (>= 2.2.5) [Installed]
perlapi-5.10.0
libtext-charwidth-perl
  Depends: libc6 (>= 2.2.5) [Installed]
  Depends: perl-base (>= 5.10.0-13) [Installed]
  Depends: perlapi-5.10.0 [NotInstalled]
libtext-iconv-perl
  Depends: libc6 (>= 2.2.5) [Installed]
  Depends: perl-base (>= 5.10.0-13) [Installed]
  Depends: perlapi-5.10.0 [NotInstalled]
libtext-wrapi18n-perl
  Depends: libtext-charwidth-perl [Installed]
debconf-2.0
  • Where are the version numbers for installed dependencies? How can I simply get each one, on a line, with this information? – detly Mar 9 '15 at 4:26
  • apt-rdepends does not provide that information. The -p flag does give some information about the package. This is probably the best one can do with existing tools. To do better, you'll have to write a script or customize apt-rdepends. Feel free to file a wishlist bug on apt-rdepends. – Faheem Mitha Mar 9 '15 at 4:31
  • I'd be interested to know why this was downvoted. – Faheem Mitha Mar 9 '15 at 4:44
  • Because it seems like you didn't really read the question. I explicitly mentioned "recursive dependencies" and "currently installed version" in the first sentence of the question. I also linked to a similar question, explaining the extra requirement with mine. This doesn't add anything that's not already answered elsewhere on this site (including the linked question). – detly Mar 9 '15 at 4:47
  • @detly I see. First, as I explained, I think this answer is as good as you are going to get with existing tools. Second, you aren't going to improve your chances of getting an answer or increase the motivation of people who are trying to help you by downvoting them. And yes, I did read the question. – Faheem Mitha Mar 9 '15 at 4:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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