GNU bug report logs - #10281
du: hard-links counting with multiple arguments (commit

Previous Next

Package: coreutils;

Reported by: Paul Eggert <eggert <at> cs.ucla.edu>

Date: Mon, 12 Dec 2011 18:02:02 UTC

Severity: wishlist

Tags: wontfix

Merged with 10282, 11526

Done: Assaf Gordon <assafgordon <at> gmail.com>

Bug is archived. No further changes may be made.

Full log


Message #58 received at 10281 <at> debbugs.gnu.org (full text, mbox):

From: "Alan Curry" <pacman-cu <at> kosh.dhis.org>
To: 10281 <at> debbugs.gnu.org
Subject: Re: bug#10281: change in behavior of du with multiple arguments
	(commit
Date: Sat, 17 Dec 2011 03:39:55 -0500 (GMT+5)
Paul Eggert writes:
> 
> On 12/16/11 18:36, Alan Curry wrote:
> > The straightforward method would be to simply the directory you intend to
> > remove and keep track of the discrepancy between st_nlink and how many links
> > you've seen.
> 
> Sorry, I can't parse that.  But whatever it is, it sounds like you're
> talking about what one could do with a program written in C, not with
> either GNU or Solaris du.

Yes, I'm saying that du is just not the tool for this job, although you've
managed to twist it to fit.

The "predict free space after rm -rf foo" operation can be done without
searching other directories and without requiring the user to specify a list
of other directories that might contain links. What you do with du is kludgy
by comparison.

[...]
> Of course I'd never want to do that in an actual link farm: it's tricky
> and brittle and could mess up currently-running builds.  But the point is that
> GNU du is not being inefficient here, any more than Solaris du is.
> 

By comparison to a proper tool which doesn't do any unnecessary traversals of
extra directories, your use of du is slow and brittle (if the user forgets
an alternate directory containing a link, the result is wrong) and has only
the slight advantage of already being implemented.

Here's a working outline of the single-traversal method. I wouldn't suggest
that du should contain equivalent code. A single-purpose perl script, even
without pretty output formatting, feels clean enough to me. Since I've gone
to the trouble (not much) of writing it, I'll keep it as ~/bin/predict_rm_rf
for future use.

#!/usr/bin/perl -W
use strict;
use File::Find;

@ARGV or die "Usage: $0 directory [directory ...]\n";

my $total = 0;
my %pending = ();

File::Find::find({wanted => sub {
  my ($dev,$ino,$nlink,$blocks) = (lstat($_))[0,1,3,12];
  if(-d _ || $nlink==1) {
    $total += $blocks;
    return;
  }
  if($nlink == ++$pending{"$dev.$ino"}) {
    delete $pending{"$dev.$ino"};
    $total += $blocks;
  }
}}, @ARGV);

print "$total blocks would be freed by rm -rf @ARGV\n";
__END__

-- 
Alan Curry




This bug report was last modified 6 years and 303 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.