views:

1785

answers:

9

I know this will delete everything in a subdirectory and below it:

rm -rf <subdir-name>

But how do you delete everything in the current directory as well as every subdirectory below it and the contents of all of those subdirectories?

+6  A: 

Use

rm -rf *

Update: The . stands for current directory, but we cannot use this. The command seems to have explicit checks for . and ... Use the wildcard globbing instead. But this can be risky.

A safer version IMO is to use:

rm -ri *

(this prompts you for confirmation before deleting every file/directory.)

dirkgently
"Can be risky" is wondefully laconic.
Lars Wirzenius
When doing things like this, I've found a quick ls -r . first lets you see what you are going to delete. Useful to give a quick idea that you aren't going to delete the whole disk...
Rich Bradshaw
Why is it riskier than rm -rf <subdir-name>?
Yen
@liw.fi: My .bashrc typically has this: alias rm="rm -i".
dirkgently
@Yen -- because if you do it in the wrong place you can get disastrous results. Using a specific name in the wrong place can only go wrong if the same subdirectory happens to exist there.
tvanfosson
Is there any possibility that it follows ".." and tries to remove parent directories? Not that i would think it would, but i better don't try it out on my box.
Johannes Schaub - litb
You cannot possibly delete the parent while residing in the child.
dirkgently
When I tried to run this command it failed, saying: rm: cannot remove `.' or `..'
Yen
Then you are left with no other option but to use the * wildcard expression.
dirkgently
i've done this in the past: rm -rf {.*,*}
Johannes Schaub - litb
A long time ago, I read a wonderfully inspiring story of a "rm -rf *" executed in the root directory. The author caught it before it finished with /bin, and reconstructed the system using only commands late in the alphabet (the earlier ones having been deleted).
David Thornley
@David: You're probably thinking about this story: http://www.ee.ryerson.ca/~elf/hack/recovery.html
sth
+2  A: 

make sure you are in the correct directory

rm -rf *
digitaljoel
This does not delete files or subdirectories whose name starts with a period.
Lars Wirzenius
true. in my testing, neither does rm -rf . tvanfosson has the best solution IMO with his "cd ..; rm -rf <dir-to-remove>"
digitaljoel
+3  A: 

rm -rf *

Don't do it, it's dangerous. MAKE SURE YOUR IN THE RIGHT DIRECTORY.

nkassis
+21  A: 

Practice safe computing. Simply go up one level in the hierarchy and don't use a wildcard expression:

cd ..; rm -rf <dir-to-remove>
tvanfosson
Why is this safer?
Yen
Because you are specifically matching a named directory and are thus less likely to delete something that you don't intend to delete.
tvanfosson
True. I could see myself doing that pretty easily.
Yen
doesn't it delete the directory itself too? You have to do mkdir <dir-to-remove> afterwards. But then any hardlink referring to that directory will be a distinct directory afterwards.
Johannes Schaub - litb
litb, I know I have a filesystem that allows hardlinks to directories, but I really doubt you have it too.
Joshua
Agree. Note: "rm -rf ." would leave you in an undertimate state with no current directory. Unix abhors an indeterminate state.
le dorfier
@Joshua I have a filesystem that allows hardlinks to directories too; it's called HFS+ and anyone who is running Mac OS X 10.5 and higher has it too.
Brian Campbell
@Joshua, I wasn't aware that i can't do directory hard-links in linux with ext3. But i just tried and it didn't let me do it. Good point dude :)
Johannes Schaub - litb
+5  A: 

Will delete all files/directories below the current one.

find -mindepth 1 -delete

If you want to do the same with another directory whose name you have, you can just name that

find <name-of-directory> -mindepth 1 -delete

If you want to remove not only the sub-directories and files of it, but also the directory itself, omit -mindepth 1. Do it without the -delete to get a list of the things that will be removed.

Johannes Schaub - litb
Note that it seems like you don't need "-mindepth 1" if removing everything below the current directory. It never seems to remove the current directory. "find -delete" is enough then. Though, would be nice if someone has some official reference for that
Johannes Schaub - litb
+2  A: 

It is correct that rm –rf . will remove everything in the current directly including any subdirectories and their content. The single dot (.) means the current directory. be carefull not to do rm -rf .. since the double dot (..) means the previous directory.

This being said, if you are like me and have multiple terminal windows open at the same time, you'd better be safe and use rm -ir . Lets look at the command arguments to understand why.

First, if you look at the rm command man page (man rm under most Unix) you notice that –r means "remove the contents of directories recursively". So, doing rm -r . alone would delete everything in the current directory and everything bellow it.

In rm –rf . the added -f means "ignore nonexistent files, never prompt". That command deletes all the files and directories in the current directory and never prompts you to confirm you really want to do that. -f is particularly dangerous if you run the command under a privilege user since you could delete the content of any directory without getting a chance to make sure that's really what you want.

On the otherhand, in rm -ri . the -i that replaces the -f means "prompt before any removal". This means you'll get a chance to say "oups! that's not what I want" before rm goes happily delete all your files.

In my early sysadmin days I did an rm -rf / on a system while logged with full privileges (root). The result was two days passed a restoring the system from backups. That's why I now employ rm -ri now.

Pierre-Luc Simard
+1  A: 

This simplest safe & general solution is probably:

find -mindepth 1 -maxdepth 1 -print0 | xargs -0 rm -rf
mark
+3  A: 

What I always do is type

rm -rf *

and then hit ESC-*, and bash will expand the * to an explicit list of files and directories in the current working directory.

The benefits are:

  • I can review the list of files to delete before hitting ENTER.
  • The command history will not contain "rm -rf *" with the wildcard intact, which might then be accidentally reused in the wrong place at the wrong time. Instead, the command history will have the actual file names in there.
  • It has also become handy once or twice to answer "wait a second... which files did I just delete?". The file names are visible in the terminal scrollback buffer or the command history.

In fact, I like this so much that I've made it the default behavior for TAB with this line in .bashrc:

bind TAB:insert-completions
Ville Laurikari
+1 just for the ESC-* expansion, that was new to me.
Jason Day
A: 

How about:

rm -rf "$(pwd -P)"/*
that one is just showing off :-) but it's cool anyway
Jeremy Wall