[NTLUG:Discuss] rm doesn't recurse
Steve Baker
sjbaker1 at airmail.net
Fri May 7 09:35:42 CDT 2004
Kenneth Loafman wrote:
> I like the rm -r method myself. Since its recursive, it does not expand
> all the arguments to the command line. I have run across cases where
> expanding the find blows the command line length out of the water.
No! There *isn't* an "rm -r" method. If you say:
rm -r *.zip
...then what will happen is:
1) The shell will search for all files in the current directory
that match the '*.zip' pattern. Now we have something like:
rm -r a.zip b.zip c.zip
2) rm now starts running. It has NO IDEA that there was a wildcard
on the command line.
3) rm says - OK look through my list of arguments - and remove each
one recursively (because of the '-r').
4) None of the command line arguments are directories - so it just
removes those three zip files and doesn't look into any sub-directories.
What ever approach you take, SOMETHING has to search through the directories
beneath this one, finding files that match some pattern.
The tool that has historically been responsible for searching through piles
of directories matching patterns (dates, access rights, ownership, file type,
etc) is 'find'.
So - all good solutions to doing this are going to entail calling 'find'.
There are perhaps three ways to take the results of 'find' and to pass them
to 'rm'.
1) You can put the find command between back-quotes (`). This tells the shell
to run the command between the back-quotes and replace that command with the
results of running it.
eg:
rm `find . -name \*.zip`
You are correct in saying that this is A BAD IDEA because there is a hard
limit on the maximum size of a shell command line (I think it's 10k bytes
or so). If the combined lengths of the file names of all those zip files
exceeds 10k (don't forget the spaces between them)...then you'll get a shell
error.
So - back-quote methods *suck*.
2) You could redirect the results of find into another command's standard input.
However, 'rm' doesn't have an option to take the list of files from the command
line. There is a program (xargs) that can take a list of files on standard input
and convert it to a list.
eg:
find . -name \*.zip | xargs rm {}
This is a perfectly good solution - as 'find' produces matching filenames, it
passes them to xargs which runs the 'rm' command with that file as it's argument.
3) Fortunately, the designers of the 'find' program thought of this. There is an
option to 'find' that works much like 'xargs' - but saves using a pipe and an
extra command:
eg:
find . -name \*.zip -exec rm {}
The 'for' loop solution that someone posted earlier is a type (1) solution because
it puts the 'find' command into back-quotes.
---------------------------- Steve Baker -------------------------
HomeEmail: <sjbaker1 at airmail.net> WorkEmail: <sjbaker at link.com>
HomePage : http://www.sjbaker.org
Projects : http://plib.sf.net http://tuxaqfh.sf.net
http://tuxkart.sf.net http://prettypoly.sf.net
-----BEGIN GEEK CODE BLOCK-----
GCS d-- s:+ a+ C++++$ UL+++$ P--- L++++$ E--- W+++ N o+ K? w--- !O M-
V-- PS++ PE- Y-- PGP-- t+ 5 X R+++ tv b++ DI++ D G+ e++ h--(-) r+++ y++++
-----END GEEK CODE BLOCK-----
More information about the Discuss
mailing list