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

Re: file management



On Thursday 27 November 2003, at 13 h 25, the keyboard of Stan Pinte 
<stanpinte@fastmail.fm> wrote:

> savez-vous comment on peut détecter tous les fichiers qui ne sont pas 
> gérés par des packets debian sur son système?

Lire status pour trouver la liste des paquetages, faire un "dpkg -L" pour la liste des fichiers, un find pour avoir *tous* les fichiers et comparer les deux listes ?

Je joins le source de mon programme gorets qui fait presque cela (il fait les deux première étapes, pour trouver quels paquetages prennent le plus de place).

"Resistance is futile. You will be packaged."

#!/usr/bin/perl

# $Id: gorets,v 1.5 2000/11/20 20:51:13 bortz Exp $

use Getopt::Long;

$VERSION = 1.2;
$statusfile = '/var/lib/dpkg/status';
$max = 15;
$verbose = 0;
$debug = 0;
$filter = "";

%optctl = ("maximum" => \$max, 
	   "verbose" => \$verbose, "debug" => \$debug,
	   "filter" => \$filter);
GetOptions(\%optctl, "maximum=i", "verbose!", "debug:i", "filter=s") or 
    die "$0 syntax error";

if ($verbose) {
  print "$0: (gorets), version $VERSION, CVS ", '$Revision: 1.5 $', "\n";
}

$filesystem = shift (@ARGV);

if (! $filesystem) {
    die "Usage: $0 filesystem";
}

($ref_dev,$ref_ino,$ref_mode,$ref_nlink,$ref_uid,$ref_gid,
 $ref_rdev,$ref_size,
 $ref_atime,$ref_mtime,$ref_ctime,
 $ref_blksize,$ref_blocks) = stat($filesystem);

if (! $ref_dev) {
    die "$0: unknown (or unreadable) filesystem $filesystem";
}

if (-e $statusfile) {
	open (PKG_SOURCE, "< $statusfile") or
	    die "Cannot open $statusfile - $!\n";
	$/ = "";  # Snarf a paragraph at a time
      PACKAGE:
	while (<PKG_SOURCE>) {
	    $clump = $_;
	    (@pkglines) = split(/\n/, $clump);
	    if($#pkglines > 3) {
		foreach(@pkglines) {
		    $index++;
		    if(/^Package:/) {
			($label, $pkg) =  split(/:\s+/,$_,2);
			if ($filter and ($pkg !~ /$filter/o)) {
			    next PACKAGE;
			}
			#if ($pkg_count >= 20) {
			#    last PACKAGE;
			#}
			$pkg_count++;
		    }
		    if (/^Status:/) {
			($label,  $pkgstatus) = split(/:\s+/,$_,2);
			$pkg_status{$pkg} = $pkgstatus;
			($plan, $state, $status) = split(/\s+/,$pkgstatus);
			if ($status eq "installed") {
			    $packages{$pkg} = 1;
			}
			next PACKAGE;
		    }
		}
	    }
	}
    }
else {
    die "No status file $statusfile??? Is it a Debian machine?";
}

$/ = "\n";
foreach $pkg (keys (%packages)) {
    $pkg_size = 0;
    open (DPKG, "dpkg --listfiles $pkg |") or
	die "Cannot run dpkg: $!";
    while (<DPKG>) {
	$clump = $_;
	chomp $clump;
	$file = $clump;
	if ($file eq '/.') {
	    next;
	}
	if (! $file) {
	    next;
	}
	if (-l $file) {
	    next;
	}
	if (! -f $file) {
	    next;
	}
	($file_dev,$file_ino,$file_mode,$file_nlink,
	 $file_uid,$file_gid,$file_rdev,$file_size,
	 $file_atime,$file_mtime,$file_ctime,
	 $file_blksize,$file_blocks) = stat ($file);
	if (! $file_dev) {
	    print STDERR "$0: cannot find $file (of $pkg)\n";
	}
	if ($file_dev == $ref_dev) {
	    if ($debug >= 3) {
		print "$file (of $pkg) is on the filesystem (size $file_size)\n";
	    }
	    $pkg_size += $file_size;
	    $total_size += $file_size;
	}
    }
    close (DPKG);
    $packages {$pkg} = $pkg_size;
}

if ($verbose) {
    print "Total packages: $pkg_count\n";
    print "Total size on $filesystem: ", int($total_size/1024), " kilobytes\n";
}

$pkg_count = 0;
foreach $pkg (reverse sort by_size keys (%packages)) {
    print $pkg, ": ", int ($packages{$pkg}/1024), " kilobytes\n";
    $pkg_count++;
    if ($pkg_count > $max) {
	last;
    }
}

sub by_size {
    $packages{$a} <=> $packages{$b};
}

__END__

=head1 NAME

gorets - utility to find the Debian packages who eat disk space

=head1 SYNOPSIS

B<gorets> [I<options>] filesystem

=head1 DESCRIPTION

B<gorets> (BTW, it means something like "greedy pigs" in French) is
here to help the system administrator of a Debian machine to find
B<which> packages are eating disk space on a B<given filesystem>.

B<gorets> finds, for each installed package (you can restrict the list
of packages with the I<--filter> option), which files belongs to the
filesystem you indicated and B<gorets> add their sizes. It
produces a report with (if you use the I<--verbose> option)
the total number of packages, the total size occupied and the list,
ordered by reverse use of disk space, of packages.

=head1 OPTIONS

=over 12

=item B<-v> B<--verbose> 

Add some details to the final listing.

=item B<-m> B<--maximum> I<number>

Limit the list of packages in the final report to the number given 
(default is 15).

=item B<-f> B<--filter> I<regular expression>

Restrict the examination of files to packages which match
the regular expression (in Perl syntax).

=item B<-d> B<--debug> I<level>

Add details (the higher the level, the more details you get) about
    what it does. Useful only for the developer.

=back

=head1 BUGS

Files with hard links are counted several times. I hope hard links are
uncommon in Debian packages.

The (small) size of directories and symbolic links is not counted at all.

=head1 AUTHOR/COPYRIGHT

Copyright 2000 Stephane Bortzmeyer <bortzmeyer@debian.org>
Free software; see the GNU General Public Licence version 2. 
No warranty.





Reply to: