Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

This question is a logical continuation of http://serverfault.com/questions/45245/how-can-i-delete-all-files-from-a-directory-when-it-reports-argument-list-too-lo

I have

drwxr-xr-x  2 doreshkin doreshkin 198291456 Apr  6 21:35 session_data

I tried

find session_data -type f -delete
find session_data -type f | xargs rm -f
find session_data -maxdepth 1 -type f -print0 | xargs -r0 rm -f

The result is the same:

find: memory exhausted

What can I do to remove this directory?

share|improve this question
1  
Are there any reasons why not to use rm -r session_data ? –  L.R. Apr 6 '10 at 18:34
    
@L.R. I couldn't wait to see when it ends. Perhaps I'll do another try. –  codeholic Apr 6 '10 at 18:39
4  
Blowing the directory away with rm -r is probably the easiest option :) –  voretaq7 Apr 6 '10 at 18:40
1  
I agree with L.R. Your previous post only mentions that you tried rm * -f but not any mention of using rm -r –  Matt Beckman Apr 6 '10 at 18:41

6 Answers 6

up vote 2 down vote accepted

It sounds like a problem with find. I noticed a few bug reports of people getting that error with a specific version of GNU findutils.

You can try replacing "find" with "ls" and "grep". Something like this:

cd somedir
\ls -f | grep "something" | xargs -d "\n" rm

The backslash on \ls instead ls tells bash to ignore any aliases that will affect your output format. You could also say /bin/ls if you forget the backslash trick. The -f option tells it to disable sorting (which saves time/memory) and include hidden files. The -d "\n" argument to xargs tells it split on newlines instead of spaces. Note that -d isn't supported on all versions of xargs, which is a shame.

Note that ls something* won't work, since the something* is expanded in bash, not by ls, and will result in an "argument list too long" error. Thats why you pipe the result through grep.

share|improve this answer
2  
ls -f skips sorting the output alphabetically, thus being both quicker and requiring less memory. –  MattBianco Aug 3 '12 at 12:20
    
@MattBianco updated –  tylerl Aug 3 '12 at 17:17

Piping find results through head seems to work for me (I have a similar problem where security camera shots from 6 cameras got uploaded once a minute)

find . -type f | head -1000 | xargs rm

If it does, loop it:

for i in {1..999}
do
   find . -type f | head -1000 | xargs rm
done

Replace 999 with how many thousands of files are in there (if you know).

share|improve this answer

Try using ls instead of find (ls -1 | xargs rm).

Or

Use a for loop over the output of ls

#!/bin/sh
for i in `ls -1`; do
  rm $i
done

(in both those cases if you're still having trouble the shell may be hitting a memory ceiling: try piping ls through head to shorten the list)

Or

Write it in perl/C/etc. (iterating over readdir's output & garbage-collecting as you go)

...there are probably more "Or" cases, but these spring immediately to mind.

share|improve this answer
    
See also the answers to your original question (which detail a whole bunch of other great alternatives besides the ones I list above) –  voretaq7 Apr 6 '10 at 18:40

I wonder what a recent version of rsync would do with a empty directory as the source and the --delete option...

share|improve this answer
find . -type f -print | awk '{ print "rm \"" $1 "\""} | sh
share|improve this answer

Just run rm as part of your find command. No need for pipes/xargs/fancy printing.

find . -exec rm -f {} +

share|improve this answer
    
If the find command is running out of memory because of the size of the tree this may not help... –  voretaq7 Nov 12 '12 at 5:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.