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.

This is a correct way to clean current directory right?

rm -r * .
share|improve this question

5 Answers 5

up vote 4 down vote accepted

I normally just move one level up in the hierarchy, then remove the directory by name and recreate it:

cd ..
rm -rf dirname
mkdir dirname
cd dirname

because that eliminates the error case of using rm -rf * in the wrong directory.

Note: If the directory has non-standard permissions or is owned by some other account, then you'll lose that when you delete and re-create the directory. That's not something that comes up very often for me, but it's worth thinking about.

If I needed to do this in a script, I'd probably make a function that saves the current directory, moves up a level, deletes and creates the new empty dir, and moves there.

share|improve this answer
    
+1 It also eliminates the possibility of overflowing the command-line args. IIRC, you can only have 1k bytes for cmd args, so rm * may expand to more than that. Recreating the dir IMHO is the best option (unless you have hardlinks, but that's just dirty). –  tjameson Jul 13 '13 at 18:31
    
I'm not sure this approach guarantees that dirname is created with the same permissions/ownership it had before you deleted it, might be a good idea to check for that before deleting. –  AnonymousLurker Jul 13 '13 at 18:53
    
@AnonymousLurker, I did mention the permissions issue. This is the 90% solution for me - I rarely have directories with odd permissions (at least compared to the number of directories with weirdly-named files). –  Mark Bessey Jul 13 '13 at 20:59
1  
@MarkBessey I suggest you put a more visible word of caution (regarding permissions on the directory) into your answer. –  guntbert Jul 13 '13 at 21:22

No, and for several reasons: 1) that command will try to remove ., which is the current directory, and will thus fail; 2) that command will not remove "hidden" files that begin with a '.' character; 3) the command will not remove directories.

You could use rm -rf *. This will remove all files and directories, but it will not remove the dotfiles. You could use find . -type f | xargs rm to remove all files including hidden ones, but this won't remove directories.

So, you can use this:

$ find . -print0 -type f -o -type d -not -name '\.' | xargs -0 rm -rf

Here you recursively find all files and directories (as long as they are not called '.') and then remove them. The -print0 and -0 arguments allow it to correctly handle filenames with whitespace in their names.

share|improve this answer
2  
This code won't delete all items. Just think of an item with a space in its name. So better use -print0 with find and -0 with xargs. –  Shi Jul 13 '13 at 12:46
    
You're right, thanks. I edited it. –  Brandon Invergo Jul 13 '13 at 13:05
    
Is Unix much different from Linux? I can use rm --recursive * .*[^.]* on Linux, and was wondering if this would work on Unix. –  Paddy Landau Jul 13 '13 at 13:55
1  
@PaddyLandau That's not a comment to this answer, really; it's a separate question. And "Unix" is a very broad term, encompassing everything from HP-UX and AIX to Mac OS X. That said, it looks to me like that rm command would remove all non-dot-files, and all dot-files which contain at least one non-dot character. Try touch ... (yes, three periods), then running it. –  Michael Kjörling Jul 13 '13 at 14:22
    
@MichaelKjörling — thanks, but I was offering this as an alternative. I wasn't sure if it would work on Unix (I use Linux), which is why I posted a comment instead of a separate answer. If it works on Linux, I'd consider it a simple answer. BTW, touch ... does indeed create a hidden file called ... in Linux. –  Paddy Landau Jul 13 '13 at 20:40

You can do this, if the -mindepth and -delete switches are available:

find . -mindepth 1 -delete

If you want to stick with POSIX, you can do this (as seen on unix.com):

find . \( ! -name . -prune \) -exec rm -rf {} \+
share|improve this answer

One easy solution if you don't want to use find is to remove the current directory then recreate it:

rm -rf "`pwd`" && mkdir "`pwd`" && cd "`pwd`"
share|improve this answer
    
You'd probably want to cache pwd. I'm not sure if this would work properly after you delete it. _dir=$(pwd) ; rm -rf "$_dir" && .... Haven't tested it though, so I could be wrong. –  tjameson Jul 13 '13 at 18:26

The find-based answers are a bit more portable, which is mostly useful for if you're using an older *nix system. They will also work better if you are dealing with directories with very large numbers of files -- the solution here will break on files numbering in the hundreds of thousands, though the exact number varies from system to system.

However, if you are dealing with a more reasonable number of files, and assuming your shell is bash version 4 or above, you can use a very similar approach to that tried in your question with the dotglob shell option:

shopt -s dotglob
rm -r ./*

Dotglob means that using a glob (*) will match files beginning with a dot (which are by default treated as hidden files by the shell), but it won't match . or .. (the current directory or the one above it). I prefer to put ./ before any globs, because that protects against any files that might start with a -, which are treated as options by by most commands and so can cause problems. An alternative would be to use:

rm -r -- *

-- is an almost-universal option meaning 'end of options': most of the core commands use it, but you may find that some lesser-used ones or custom scripts don't, which is why I prefer using ./* instead.

You can unset dotglob once you are done with:

shopt -u dotglob

Another way of doing it without messing around with shell options would be:

rm -r ./* .[^.]*

The first glob ./* will match everything in the current directory that doesn't begin with a dot, while the second one .[^.]* matches everything that begins with a dot, followed by a single non-dot character, followed by any number of other characters. You have to use that instead of .* to avoid matching . and ..; however, this won't match any files beginning with two dots, whereas dotglob will handle them correctly.

It's probably easier to just cd .., then rm -r the directory you want to clear and then recreate it with mkdir. This may cause problems in some situations, though, as you may end up altering the directory's permissions.

share|improve this answer
    
If you have a huge directory listing, this could fail because of the number of CMD args. –  tjameson Jul 13 '13 at 18:33
    
@tjameson yes, though that would have to be a pretty huge number of files... –  evilsoup Jul 13 '13 at 18:50
    
I ran into that just this past week at work. It was something around 500,000 files... –  tjameson Jul 13 '13 at 22:43
    
@tjameson ...well, OK then, I'll edit in a disclaimer –  evilsoup Jul 14 '13 at 8:41

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.