thepler has asked for the wisdom of the Perl Monks concerning the following question:

I must be missing something.

UPDATE: I was missing something. As ikegami points out in the comments, rmtree("foo", 0, 0) does the job. That's what I get for not carefully reading the docs.

Why is doing rm -rf, but in perl, so hard? Before you point to rmtree in File::Path, know this:

$ mkdir foo $ touch foo/bar $ chmod 444 foo/bar $ perl -e 'use File::Path "rmtree"; rmtree("foo", 0, 1)' Can't remove directory foo: Directory not empty at -e line 1 $ ls foo bar

Not only did it not remove foo, it threw a warning. I've stepped through rmtree, and I see no flags/args I can set/pass to make it do the right thing. Maybe I've missed it though...

Note how unlike rm -rf this is:

$ rm -rf foo $ ls foo ls: foo: No such file or directory

Yay! It did what I asked and didn't complain.

Path::Class and File::Remove both use File::Path::rmtree underneath, so they're just as unhelpful. So what to do?

use Path::Class; my $dir = dir('foo'); $dir->recurse(callback => sub { unlink $_[0] if !$_[0]->is_dir; }); $dir->rmtree(0, 1);

That works, but look how clunky and un-concise it is. I'm not asking it to be as concise as "rm -rf", but surely it should fit on one line. And note how unlink() happliy removes my 444 file, yet rmtree won't even try.

So, here are my requirements:

Thanks,
Todd

Replies are listed 'Best First'.
Re: concise perl rm -rf idiom that works?
by ikegami (Patriarch) on Mar 21, 2007 at 22:47 UTC

    -f is the default behaviour. You are turning it off.

    Change
    perl -e 'use File::Path "rmtree"; rmtree("foo", 0, 1)'
    to
    perl -e 'use File::Path "rmtree"; rmtree("foo", 0, 0)'
    or just
    perl -e 'use File::Path "rmtree"; rmtree("foo")'

      Much thanks! Not sure how I missed that.