I am trying to remove large amount of mails (mostly mail delivery failed) from my server using

 rm -rf /home/*/mail/new/*

And I am getting -bash: /usr/bin/rm: Argument list too long

I tried using find

find /home/*/mail/new/ -mindepth 1 -delete

But after 20 minutes it looks like it's not doing anything.

How do I use for loop to delete everything (directories, files, dotfiles) within /home/*/mail/new/

Something like this

for f in /home/*/mail/new/*.*~; do
        # if it is a file, delete it
    if [  -f $f ]
        rm "$f"

Please help me rewrite this command to delete files AND folders and everything within /home/*/mail/new/

EDIT: My question is unique because it's about doing that in FOR loop.

  • The find command looks fine. If you want to show what it's, doing use -print -delete – jordanm Feb 28 '17 at 19:47
  • I think for has better performance than find. – Luka Feb 28 '17 at 19:50
  • 1
    It doesn't. Shell loops are slow. Nothing will be slower than the loop and find should be orders of magnitude faster. – terdon Feb 28 '17 at 19:56
  • not duplicate. That is not what question is about, i asked how to remove all files, folders and dotfiles using for loop, and there is no answer on internet for that. – Luka Feb 28 '17 at 20:05

The problem is that /home/*/mail/new/* expands to too many file names. The simplest solution is to delete the directory instead:

rm -rf /home/*/mail/new/

Alternatively, use your find command. It should work, it will just be slower.

Or, if you need the new directories use a loop to find them, delete and recreate them:

for d in /home/*/mail/new/; do
    rm -rf "$d" && mkdir "$d"

The loop you were trying to write (but don't use this, it is very slow and inefficient) is something like:

for f in /home/*/mail/new/* /home/*/mail/new/.*; do
    rm -rf "$f"

No need to test for files if you want to delete everything, just use rm -rf and both directories and files can be deleted by the same command. It will complain about not being ab;e to delete . and .. but you can ignore that. Or, if you want to be super clean and avoid the errors, you can do this in bash:

shopt -s dotglob
for f in /home/*/mail/new/*; do
        rm -rf "$f"
  • Then my only solution is to delete whole new directory and recreate it. – Luka Feb 28 '17 at 19:59
  • @Luka no, you can use your find command and wait a bit. But yes, deleting and recreating is by far the easiest and fastest way. I also added the loop you were asking for but that will be far slower than anything else. – terdon Feb 28 '17 at 20:01
  • I added nice -n -20 to find command, and its a lot faster – Luka Feb 28 '17 at 20:16
  • @Luka OK, that suggests you have a pretty busy machine and other things were taking precedence. The main take home message here is that shell loops are slow and inefficient, pretty much anything will be faster than a shell loop. – terdon Feb 28 '17 at 22:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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