On the dangers of 'rm'

Even if you’re brand new to Terminal, I hope someone has given you this valuable advice:

Be very careful when using the rm command to remove files and folders!

The Unix file and folder deletion tool rm is one of the most dangerous commands around. After all, no one likes to obliterate precious files by accident. Today, I’ll show you just how hazardous it can be and walk you through some techniques that will help you work with it safely.

Why is rm potentially dangerous?

There are two main reasons why you should respect and fear the rm command. First off, when you remove an item with rm it’s gone for good as soon as you press Return. You can’t fish it out of the trash can if you change your mind. Yes, there’s a (slender) chance you may be able to recover some or all of your deleted files using a third-party program, such as SubRosaSoft’s $90 FileSalvage. (To increase your odds of recovering the files you need to stop using your Mac and immediately run the file recovery utility. The longer you use your Mac after making a mistake, the less chance you have of recovering your data.) But let’s face it, once you rm something, it’s likely gone for good. Hasta la vista, data!

The second danger with rm is that, being a Unix command, it’s quite literal, and it will do exactly what’s asked—even if the request means the destruction of the very system that rm is running on. What does that mean? It means that rm is very powerful, with the ability to remove files from anywhere on your machine, and that one small typo could lead to very big negative consequences. Consider the following example:

WARNING: Please do not try the command listed in the following example. It will do VERY BAD THINGS to your machine. Really. Really, really bad. Do not try this at home. Do not try this on a friend’s computer. Do not try this period. You have been warned.

Assume you were working on something in Terminal in your home folder, and you remembered that your wife wanted you to remove something from her Documents folder. She no longer needed her Work Documents folder, as she had recently changed employers. Being the lazy efficient type of person that you are, you realize that you can do this directly from Terminal, without even changing directories. So you type:

sudo rm -rf /Users/spouse/Documents/Work Documents

(The -rf flags mean “recursively ( r ) traverse the folder, removing all files and sub-folders,” and “force ( f ) removal, ignoring permissions.” You’d have to use both these options, along with sudo, to remove a folder from another user’s directory.)

Sounds like a fine idea, but as soon as you press Return, you put in motion a very rapid and very painful action—you’ve just permanently deleted your own Documents folder, along with everything in it! Yikes! Of course, you have a recent backup (right?!), so it’s only a minor inconvenience and not a major disaster. But how did this happen, and how can you prevent it in the future?

What Happened?

In the above example, there was exactly one character missing—a single backslash—and that’s what caused the devastation. In Terminal, if you’re referencing a file or folder with a name including a space, you must either enclose its name in quotes, or put a backslash before the space, like this:

	"/Users/spouse/Documents/Work Documents"
	/Users/spouse/Documents/Work Documents
	

The problem is that Terminal sees the space in your original command, and interprets it as a delimiter—that is, something used to separate arguments on the command line. And the rm command accepts multiple files on one input line, as in rm file1 file2 file3. As a result, your single rm command was actually two commands:

	rm -rf /Users/spouse/Documents/Work
	rm -rf Documents
	

Now, the first rm will fail, assuming your spouse doesn’t have a folder simply named Work in her Documents folder. However, it doesn’t cause any sort of error message, nor does rm stop running just because it can’t find the file or folder you referenced. Instead, it notices the space, and thinks, “Ah, here’s another folder I should delete.”

Since you were working in your home folder, and the Documents folder is a top-level folder within that directory, the rm command happily does your bidding and removes it, just as you asked. Poof. All gone. You didn’t really need your dissertation anyway, did you? And since rm runs without any feedback or warnings, you won’t know something’s wrong until it’s too late. And all because you left out a simple backslash.

Note: In the example I gave, you would only lose your Documents folder if you were working in your home directory—or if you had a folder named Documents in another folder in which you were working. However, I think you can easily generalize the damage you could cause with simple mistakes.

Disaster Prevention 101

Thankfully, there are some easy steps you can take to save yourself from such disasters. The first, obviously, is to exercise extreme care when using rm, especially with the r (recursive) and f (forced) options. But even with extreme caution, we all make mistakes—nearly everyone I know, myself included, has made at least one stupid mistake with rm. So beyond common sense, what else can you do?

The Safest Solution

Short of not using rm at all, the next best solution is to always use rm -i. The -i option stands for interactive, and it forces you to manually accept each and every deletion. For instance, if you wanted to remove all the files with a name starting with “MyPic,” you’d do this:

	$ rm -i MyPic*
	remove MyPic1.jpg? y
	remove MyPic2.jpg? y
	remove MyPic3.jpg? y
	remove MyPic4.jpg? y
	

This is really the safest way to use rm, but it can get quite tedious—consider a directory with 150 files in it that you’d like to trash. There are, however, other solutions that provide some degree of safety.

The Not Quite So Safe Solution

You can also use the shell’s ability to apply the arguments from the prior command to the current command. So instead of just running rm on the folder, first do an ls to see if you’re getting what you expected. Then tell rm to use the arguments from the ls command when it runs.

For instance, if you wanted to remove all the files with a name starting with “MyPic,” you might do this:

	$ ls MyPic*
	MyPic1.jpg  MyPic2.jpg  MyPic3.jpg
	$ rm !$
	

The !$ part of this command tells the shell to grab the argument ( MyPic* ) from the last command, and use it with the current command. In this example, that means that rm will get the MyPic* argument from ls. By using the ls command first, you can see exactly what the rm command will delete. If the ls output isn’t correct, or throws an error, then you’ll see that before deleting the files.

You could also use the echo command as a “dry run” for your deletion. Instead of just running rm MyPic*, try it as echo rm MyPic* first. The output will show you what the expanded rm command would look like:

	$ echo rm MyPic*
	rm MyPic1.jpg  MyPic2.jpg  MyPic3.jpg
	

If everything looks right, hit the up arrow (to retrieve the last command), then move the cursor left and remove the word echo.

Another option you might consider is not using rm at all. Instead, use the move command, mv. Create a special “to delete” folder somewhere on your system, and use mv to put everything there first. Then, you can look through the “to delete” directory when you have time, and use rm only within that directory—or else check it from the Finder and just use the Finder’s trash. So to replicate the above MyPic example, you’d just do this:

$ mv MyPic* ~/myuser/dump_dir/

This would move all the files that start with MyPic into your dump_dir folder, from where you could later look at them at your leisure, just to make sure only the right files got moved. Once you were sure the proper files had been moved, you could then delete the files.

Handle with Care

My personal use of rm really depends on the situation, but I use some combination of the above solutions in various ways. One of my cardinal rules is that I try to never combine the r and f flags with the wildcard (the asterisk). There’s just too much that can go wrong. If I have to do something like that, I’m much more likely to use mv instead, or ls to make sure I’m deleting what I intend.

I’ll also use the i switch when I’m using the wildcard within a directory; that way, I can make sure that I’m deleting what I want to delete.

At the end of the day, it’s really up to you how well you protect yourself when using rm —it’s a very powerful tool, and (especially when used with sudo and the recursive and forced options) can do great damage to your system in a hurry. There’s nothing that will prove the value of a good, current backup faster than a misdirected rm -rf. As Spider-Man so famously learned: “With great power comes great responsibility.”

Note: This article was edited at 9:30am Pacific Time on Friday, December 9th. Edits were for style and content; there were no changes made to the Unix instructions…

  
Shop Tech Products at Amazon