Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Will rm -rf * remove all files/folders in the current directory ? I want to make sure the wildcard * won't move up in upper directories and erase all my filesystem. :D

I remember doing chmod 777 .* -R to chmod hidden files and it chmoded all my filesystem. Obviously, I was on the root account.

share|improve this question
    
This is why I'd do rm -rf ./* and explicitly specify the current directory... but Ankur seems to say it doesn't matter anyway. –  Mark Apr 2 '10 at 2:06
    
@Mark: what is the difference between .. and ./..? You can try to cd ./.. and see where you end up :) –  Johan Apr 2 '10 at 7:38
    
@Johan: No difference... I guess it just makes more sense in my crazy head :D –  Mark Apr 3 '10 at 5:12
    
@Mark: easy mistake to do :) –  Johan Apr 3 '10 at 7:21

6 Answers 6

A much easier way to empty an entire folder, also avoiding the "too many arguments" issues discussed in this answer, is to simply delete and recreate the directory itself. To make sure this works correctly when you are in a symlinked directory, use the following lines:

cd ..
rm -rf $(readlink -f yourdir) #remove the directory, treat the case of a symlink
                        # by using readlink, to recreate the linked-to directory
mkdir $(readlink -f yourdir) # recreate the directory to have it empty
cd yourdir

(If you uses yourdir instead of $(readlink -f yourdir) you'd only replace the link while the original location remains full)

share|improve this answer
1  
This can break things relying on the folder's inode, and throw away permissions, atime/mtime/ctime/btime, extended attributes, and access control lists. –  Daniel Beck Jan 18 '12 at 12:10
    
@DanielBeck thanks, good points. Although I wonder, what would validly rely on the inode apart from hardlinks (on directories, which are strongly discouraged anyway)? But permissions etc is important. So in the most general case one should probably use xargs... –  Tobias Kienzler Jan 18 '12 at 12:13
    
OS X contains a mechanism that can handle files and folders being moved around and still retain the association. Most visibly in the Open Recent Documents menu. AFAICT, it uses inodes to accomplish that internally. More info. I wouldn't be surprised if other systems implemented something similar e.g. in APIs for GUI programs. –  Daniel Beck Jan 18 '12 at 12:16

If you don't want to move one level up like mpez0 said and rm -rf this specific folder, there is a way to work on all directories/files except . and .. in the current folder by doing:

rm -rf $(ls -A)

Of course, if any of the directories/files contains one of the characters in the shell IFS special variable (e.g. space, tab, newline), you might want to change the IFS first, run the command, then restore IFS.

share|improve this answer

Since I think this question is more about what * does (and not rm), let's try another approach.


If you are unsure what the * does, you can "test" first using a harmless command like echo. Before you run this, try to guess what they will show if you run them in your home dir.

echo *
echo .*

But first let's create a playground so we can play with the stars and see what we end up with.

mkdir ~/star_test/
cd ~/star_test/
>.file1
>file2

Now in this dir we have this:

cj@zap:~/star_test$ ls -1a
.
..
.file1
file2

Now notice what the * expands into using the echo command:

cj@zap:~/star_test$ echo *
file2
cj@zap:~/star_test$ echo .*
. .. .file1

So let's see what happens with the rm command

cj@zap:~/star_test$ rm -rf *
cj@zap:~/star_test$ ls -1a
.
..
.file1

As you see he did only remove the file2, since * only expanded to file2. If you would type rm -rf .* that would be the same as writing

rm -rf . .. .file1

And to be honest, that do not look fun ;)

Hope this clarifies the * part of your question.


Update: However as Ankur Goel points out there is some kind of protection built into rm (kind of unusual for shell commands :)

Let's create a new playground:

cd ~/star_test/
mkdir -p test1/test2/test3
sudo chown root.root test1
cd test1/test2/test3/
>.file1
>file2

So now we have this again, but with test1 owned by root as protection if rm start to go berserk.

cj@zap:~/star_test/test1/test2/test3$ ls -a
.  ..  file2  .file1
cj@zap:~/star_test/test1/test2/test3$ echo .*
. .. .file1

So let's remove everything:

cj@zap:~/star_test/test1/test2/test3$ rm -rf .*
rm: cannot remove directory `.'
rm: cannot remove directory `..'
cj@zap:~/star_test/test1/test2/test3$ ls -a
.  ..  file2

And it looks like rm did not remove . and .. even if we told him to!!!

So after this long answer it turns out to be safe to remove everything in a dir with this:

rm -rf * .*

But I would use this with care, since I'm not sure all implementations of rm behaves like this!

share|improve this answer

If you want to remove a directory and all its contents, you can chdir into the parent directory and them rm -rf that directory by name, bypassing the entire globbing question. If you want to remove the contents but keep the directory, it's easiest to remove all and then recreate the directory.

It is complex to come up with a glob that will match all possible directory entries save . and ..; it's easy to come up with a simple answer (e.g., * .??*) that will work almost always in practice. This is OK for interactive use, since it's easy to remember and the times it doesn't work can be caught with a post-rm ls -a. For a script, it's easier to do the remove all and recreate the empty directory.

share|improve this answer
1  
That is what i would suggest as well: throw away the directory and done –  akira Apr 2 '10 at 14:03
    
Even thou it's not the answer it is a good idea. –  Johan Apr 3 '10 at 8:08

No, if you did not tweak your shell a lot this will not remove files or directories starting with a .. To remove them, too, you can either list them explicitly

rm -rf .file .dir

or use the right glob patterns (thanks Chris)

rm -rf .[^.]* ..?*

EDIT The point here is that you cannot use .* to match files like .file, because .* or .*? will also match .. or .. .[^.]* matches files like .file, while ..?* matches files like ..foo (* matches zero or more characters while ? matches exactly one).

share|improve this answer
1  
You also need something like ..?* to catch entries that start with “..” (e.g ..foo). –  Chris Johnsen Apr 2 '10 at 4:47
    
@Chris: OK, I started this picky madness, you are right ;) –  Benjamin Bannier Apr 2 '10 at 5:16
    
it's not only to use the "right" glob patterns, it's also about the amount of matched items. in directories with a huge amount of files the shell is most likely not able to give 50k files in one turn to rm. so, deleting the content of a directory with * is not the wisest way, imho. –  akira Apr 2 '10 at 7:06
    
I think explaining xargs is a little beyond the scope of this question. One could e.g. start thinking about that when the shell complains argument list lenghts. –  Benjamin Bannier Apr 2 '10 at 7:22
1  
i think it's not out of scope because i think OP is not sure how to achieve his ultimate problem / solution: remove all the content of the directory. OP is just doing the general "wrong" thing by having already a solution (a bad one) in mind and asking why this solution causes problems. better approach would be: "how to delete all files in a directory without deleting the directory itself?" OP's solution will cause problems due the very nature of how globbing works. –  akira Apr 2 '10 at 8:09

Yes. rm -rf will only delete files and folders in the current directory, and will not ascend up the file tree. rm will also not follow symlinks and delete the files they point to, so you don't accidentally prune other parts of your filesystem.

share|improve this answer

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.