You could do it with a pair of statements.
First, get a list of directories to remove using
find -name *.rar -exec dirname {} ';' > toremove
Next, cat toremove
to make sure it has the folders you want. Then, pass it to rm -rf
using
sed 's/^/"/g' toremove | sed 's/$/"/g' | xargs rm -r
Last, rm toremove
.
Don't forget the possibility that the server being unreachable after the rm
command had nothing to do with that. It could be a coincidence!
Most likely though, the current working directory was not what you thought, when the command was issued.
Were you root when doing this?
This is what happens when issuing the command rm -rf *
:
- The shell resolves the wildcard patterns (
*
in this case) to all files (including directories, symbolic links and device special files) that matches the used globbing pattern, in this case everything not beginning with a .
Normally, these are sorted "alphabetically" by the shell.
- The shell then forks a new process and
exec()
s the first version of rm
found in your $PATH
, with -rf
as the first argument, and the matched files, one by one as the consecutive arguments.
If the rm
that was invoked was the standard rm
command, it first parses the arguments, one by one, treating all arguments (including ones resulting from shell globbing) that begin with a -
as options until it comes to an argument that does not begin with a -
(except for commands using GNU getopt()
that accept options after non-options), or one that is exactly --
. Everything after that is considered file names.
In other words, if you had a file called (for example) --no-preserve-root
in the current directory, that would have been interpreted as an option to rm
, not as a file name to remove!
Be careful with wildcards (and with file naming). If you have a file called -r
in the current directory, the command ls *
would list the other files in reverse order, and not show the '-r' file.
In other words, if you had a file called --no-preserve-root
, that would have been passed as an option to rm
, not as a file name.
Use rm -rf -- *
to prevent that from happening, and also remove the files beginning with -
. Or simply use absolute or relative path names to make the filenames begin with something other than -
, as in: rm ./--flagfile
or rm /abs/path/to/--flagfile
.
There is also a -i
flag to rm
that makes it prompt ("interactively") before removing anything.
Best Answer
The members of
findutils
aware of it, it's for compatible with *BSD:The NEWS in findutils source code shows that they decided to keep the behavior:
[UPDATE]
Since this question become one of the hot topic, so i dive into FreeBSD source code and come out a more convincing reason.
Let's see the find utility source code of FreeBSD:
As you can see, if it doesn't filter out dot and dot-dot, then it will reach
rmdir()
C function defined by POSIX'sunistd.h
.Do a simple test, rmdir with dot/dot-dot argument will return -1:
Let's take a look how POSIX describe rmdir:
No reason was given why
shall fail
.I found
rename
explain some reason:Cyclical file system paths ?
I look over The C Programming Language (2nd Edition) and search for directory topic, surprisingly i found the code is similar:
And the comment !
"loop forever", this is same like how
rename
describe it as "cyclical file system paths" above.I slightly modify the code and to make it run in Kali Linux based on this answer:
Let's see:
It work correctly, now what if I comment out the
continue
instruction:As you can see, I have to use Ctrl+C to kill this infinitely loop program.
The '..' directory read its first entry '..' and loop forever.
Conclusion:
GNU
findutils
try to compatible withfind
utility in *BSD.find
utility in *BSD internally usermdir
POSIX-compliant C function which dot/dot-dot is not allow.The reason of
rmdir
do not allow dot/dot-dot is prevent cyclical file system paths.The C Programming Language written by K&R shows the example of how dot/dot-dot will lead to forever loop program.