[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Finding left-over libraries



Matthias Hertel wrote:
<snip>
> Well, its not clean, and it doesn't even work correctly (it doesn't
> correctly handle |-dependecies), and there are probably other bugs,
> but here is a perl script that I threw together when I was new to
> Debian (and perl) that does what you want: It lists all packages
> nothing depends on and that are not essential, and also says whether
> they are suggested or recommended by other packages. It occasionally
> gives false positives (I think the missing |-handling is to be
> blamed), and I also found a case where it gives false negatives (some
> gnome packages have circular dependencies, I think).
> 
> I wonder if all this could be done much more cleanly with libapt
> (never looked into that).
> 
> Anyway, if anybody wants to improve on this, you're welcome. Perhaps
> post it back to the list.
<snip>

Hi Matthias,

Thanks for the script - I was thinking about this issue myself,
but you've saved me the trouble.

I've enclosed an updated version which handles the "or" situation.
It now splits the whole line on whitespace and then rejects any
tokens which start with an open parenthesis or the or "or" symbol,
or end with a closing parenthesis.

If you call the program with option "-l", it'll now show all packages
if no others depend on it (as before), but now they must also contain
the string "lib" in the package name.  Crude form of filtering, but
effective.

I also caught the numeric vs string compare near the top; -w is your
friend ...

Thanks again,
Paul


#!/usr/bin/perl -w

use English;

open PKGLIST, "dpkg --get-selections |";
while (<PKGLIST>) {
  ($pkg, $sel) = split;
  push @pkglist, $pkg if $sel eq "install";
}

open STATUS, "dpkg --status @pkglist |";
$INPUT_RECORD_SEPARATOR = "";
while (<STATUS>) {
  ($package) = /^Package: (.*)$/m;
  ($essential) = /^Essential: (.*)$/m;
  ($priority) = /^Priority: (.*)$/m;
  ($size) = /^Installed-Size: (.*)$/m;
  unless ($essential) {
    push @packages, $package;
    $priorities{$package} = $priority.", ".$size."k";
  }

  do {
    foreach $p (grep {!(/^[|(]/|/\)$/)} split ' ', $foo) {
      push @{$pre_depends{$p}}, $package; 
    }
  } if ($foo) = /^Pre-Depends: (.*)$/m;

  do {
    foreach $p (grep {!(/^[|(]/|/\)$/)} split ' ', $foo) {
      { push @{$depends{$p}}, $package; }
    }
  } if ($foo) = /^Depends: (.*)$/m;

  do {
    foreach $p (grep {!(/^[|(]/|/\)$/)} split ' ', $foo) {
      { push @{$provides{$p}}, $package; }
    }
  } if ($foo) = /^Provides: (.*)$/m;

  do {
    foreach $p (grep {!(/^[|(]/|/\)$/)} split ' ', $foo) {
      { push @{$suggests{$p}}, $package; }
    }
  } if ($foo) = /^Suggests: (.*)$/m;

  do {
    foreach $p (grep {!(/^[|(]/|/\)$/)} split ' ', $foo) {
      { push @{$recommends{$p}}, $package; }
    }
  } if ($foo) = /^Recommends: (.*)$/m;
}

foreach $p (keys %provides) {
  foreach $pp (@{$provides{$p}}) {
    push @{$pre_depends{$pp}}, map $_." (via $p)", @{$pre_depends{$p}}
      if defined $pre_depends{$p};
    push @{$depends{$pp}}, map $_." (via $p)", @{$depends{$p}}
      if defined $depends{$p};
    push @{$suggests{$pp}}, map $_." (via $p)", @{$suggests{$p}}
      if defined $suggests{$p};
    push @{$recommends{$pp}}, map $_." (via $p)", @{$recommends{$p}}
      if defined $recommends{$p};
  }
}

$LIST_SEPARATOR = ", ";

$lib_flag = (defined $ARGV[0] and $ARGV[0] eq "-l");
foreach $p (@packages) {
  next if defined($pre_depends{$p}) || defined($depends{$p});
  next if $lib_flag and $p !~ /lib/;

  print "$p ($priorities{$p})";
  print "\nsuggested by: @{$suggests{$p}}" if defined $suggests{$p};
  print "\nrecommended by: @{$recommends{$p}}" if defined
$recommends{$p};
  print "\n\n";
}


Reply to: