Will rm -rf * remove all files/folders in the current directory?

Solution 1:

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).

Solution 2:

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.

Solution 3:

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!