Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

A shell function to make 'rm' move files to the trash UNIX
Command line users: Have you ever wished rm would put stuff in the Trash instead of just deleting it? After accidentally running rm -rf Desktop one day, I decided it was time to stop really deleting stuff when I ran rm. So I wrote is a shell function -- this means that the actual /bin/rm executable works like normal; only when you run rm from Terminal do files get moved to the Trash. This means that programs (and scripts) which delete files won't be affected.

So how do you use this? Open Terminal, and edit ~/.bash_profile (this is a script which is run every time you open a Terminal). Run nano ~/.bash_profile from the command prompt if you don't have a preferred editor. Add the following lines at the bottom of the file:
function rm () {
  local path
  for path in "$@"; do
    # ignore any arguments
    if [[ "$path" = -* ]]; then :
      local dst=${path##*/}
      # append the time if necessary
      while [ -e ~/.Trash/"$dst" ]; do
        dst="$dst "$(date +%H-%M-%S)
      mv "$path" ~/.Trash/"$dst"
Save the file and exit. (Hit Control-X in nano; it'll ask if you want to save, press Y and hit Enter to accept the default filename.)

Now, close all open Terminals. Open a new one. You can verify that the function exists with set -- you should see Terminal echo the lines you added above. If you see those lines, then you can test it by creating a new file and then deleting it. (Your input is after the $ on the lines below.)
$ touch newfile
$ ls -l newfile
-rw-r--r--   1 mas  mas  0 Feb 22 19:12 newfile
$ rm newfile
Now open up your Trash; you should find newfile somewhere amongst the other stuff in your trash. So now you can rm files from the shell prompt without worry. There are a few caveats, though I believe these won't affect most people:
  1. This is all very specific to bash. If you use a shell other than bash, you can't use this function. I believe bash is the default in Mac OS X, so this shouldn't be an issue.
  2. This ignores any arguments you pass to rm. Since files are going to the trash, I don't see any need for -i or -f. I also saw no reason to treat files and directories differently; after all, Finder doesn't care. If anyone feels like modifying this to handle arguments, feel free to post a revised function in the comments.
  3. Finally, I want to repeat again that this function only works in Terminal. Any programs or scripts you run will not be affected. But this also means that since the rm executable is still there, if you need to really delete something you can easily do so: /bin/rm file or /bin/rm -rf directory ignores the function and runs rm directly, so the files won't go into the Trash.
[robg adds: Back in 2003, this hint linked to rmm, a shell script that does essentially the same thing as this hint. The rmm script offers a number of additional options, such as verbose mode, force move, and optional moving of directories. It also checks for locked files and unlocks them if necessary. I felt this shorter version was a good alternative and worth posting on its own; I like that it runs as a shell function, seamlessly replacing rm in interactive mode, yet allowing rm work as usual when called via a script. I tested this one, and it works as described.]
  • Currently 2.20 / 5
  You rated: 1 / 5 (10 votes cast)

A shell function to make 'rm' move files to the trash | 28 comments | Create New Account
Click here to return to the 'A shell function to make 'rm' move files to the trash' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
A shell function to make 'rm' move files to the trash
Authored by: ubrgeek on Feb 29, '08 07:57:13AM

Very, very cool. On behalf of the others who have done things similar to, "Hmm, did I just bloody well almost delete Desktop?!!?" many thanks! :)

[ Reply to This | # ]
A shell function to make 'rm' move files to the trash
Authored by: marbx on Feb 29, '08 12:04:48PM

You're very welcome. After deleting Desktop, I was kicking myself for a day or two before I starting thinking about how to prevent it from happening again. At least some good eventually came out of it. :)

[ Reply to This | # ]
Not a good idea
Authored by: googoo on Feb 29, '08 08:28:42AM

In general, it is not a good idea to redefine basic commands like rm. You can run into problems with scripts and such that use the command. A better option would be to give your script another name (like the old rmm script) to avoid these conflicts.


[ Reply to This | # ]
Yes and no
Authored by: SeanAhern on Feb 29, '08 09:09:32AM

If you created a shell script that did this, and put it somewhere in your $PATH, I'd agree with you. But this guy did it as a shell function. This means that it only takes effect in bash shells. And if he loads functions correctly, then it would only take effect in login bash shells. This restricts it to only interactive use, exactly what you want. It no longer affects scripts and other tools.

[ Reply to This | # ]
Do not make replacement versions or aliases for common programs
Authored by: Elliot Shank on Feb 29, '08 08:31:06AM

This is bad news. Don't create "safe" versions of things like cp, mv, rm, etc.

Why? Because you'll become dependent upon them and then, when you're on some other computer which doesn't have this sort of thing applied to it, you'll be surprised when the safety features don't kick in.

Either make a habit of passing -i to these commands or use a different name for the safe version. My equivalent of this hint is called "trash". This way, when I'm on another computer that isn't set up my way, if I make a mistake, I'll get a "command not found" error, rather than destroying data.

[ Reply to This | # ]
Uniform and consistent experiences
Authored by: SeanAhern on Feb 29, '08 09:12:16AM

I guess I agree with you. But you can argue the other way as well. The poster was used to having the "safety" of the normal Finder delete operation of moving things to the Trash. Not having "safety" in the UNIX equivalent was frustrating to him. So he makes the system consistent by adding extra safety to 'rm'. It creates a more uniform experience for the poster.

[ Reply to This | # ]
Do not make replacement versions or aliases for common programs
Authored by: marbx on Feb 29, '08 11:48:01AM

For people who use several computers on a daily basis, this might be a problem. Garumph makes the same point - if you use this function often, it may be easy to forget this is something that you had to add on (kind of like Quicksilver, I think). I disagree that aliasing in protection is always a bad idea, though. For example, every time I get an account on a Solaris box, the first thing I add to my profile is:

alias killall 'echo Do not use killall on Solaris unless you really mean it\!'

It's just a handy reminder, since I don't use Solaris often enough to remember that killall works differently on Solaris.

I guess I've got two real replies to this: One, this is just an extra safety measure. I still never trash anything (or rm it) until I'm sure I don't want it anymore. When you delete something, you should consider it deleted. But it's still nice to be able to drag something back out of the trash when you need to, whether you deleted it from the Finder or from a shell prompt. Of course, if you know you're going to forget that this doesn't work on every box you work on, don't use it. But for the rest of us, it may come in handy from time to time.

Two, there's nothing stopping you from putting this in the profile on every machine you use. Well, there may (for example) be a policy against editing profiles on company servers, I suppose. But both this function and the .Trash directory are kept in your home directory. I see no reason you can't go ahead and put this on multiple machines, whether running HP-UX, Solaris, IRIX, or what have you. Of course, you'd want to have a tcsh or ksh version, unless you've upgraded to bash on all those. ;)

[ Reply to This | # ]
A shell function to make 'rm' move files to the trash
Authored by: CaptDeuce on Feb 29, '08 08:43:58AM
Open Terminal, and edit ~/.bash_profile (this is a script which is run every time you open a Terminal)

Just curious: what if you don't use the bash shell?

"Where's my other sock?" - A. Einstein

[ Reply to This | # ]

A shell function to make 'rm' move files to the trash
Authored by: hypert on Feb 29, '08 09:08:04AM
If you're using csh or tsch, add this to your .cshrc or .tcshrc file:
alias rm '\mv \!* ~/.Trash'
Feel free to call the alias "rmm" or something else that suits you. I understand the argument for doing that, but I'm too lazy to remember a million ways to call the same thing. I have an "ll" alias for "ls -l", and it's one of the WORST things, as I type "ll" all the time, even on accounts/computers. I'd rather have my alias do something instead of having me to have to re-type commands over and over. Even for "rm", as I do not accidentally delete someone else's Desktop very often...

[ Reply to This | # ]
Rewriting for tcsh, etc.
Authored by: marbx on Feb 29, '08 11:25:33AM

Then you'll have to figure out how to rewrite the function for tcsh, or whatever you do use. :)

Sorry, but I'm not familiar with programming in anything other than Bourne or bash, so I'm not the one to ask about it. Hypert's alias command is a basic step; and it's what I was using before I wrote this function. The added value of the function is in appending the time so you don't overwrite anything already in the trash, and in ignoring arguments (although that's not a big deal between rm and mv).

[ Reply to This | # ]
A shell function to make 'rm' move files to the trash
Authored by: mbenchoff on Feb 29, '08 08:58:57AM
Or you could use mv ~/.Trash filename and not have to modify anything.

[ Reply to This | # ]
A shell function to make 'rm' move files to the trash
Authored by: mbenchoff on Feb 29, '08 09:01:10AM
Whoops! Make that mv filename ~/.Trash

[ Reply to This | # ]
That's what this does
Authored by: SeanAhern on Feb 29, '08 09:16:44AM

Did you read the script? That's basically what this function does. The last statement does the mv to the Trash.

But it does a couple more things to make things easy. If you have a collision, there's something already in the Trash with the same name, it appends a timestamp. Also, it strips out any options you might have passed to what you thought was rm.

(The only other thing I'd add would be a "touch" loop, since I have a cron job that automatically deletes things in the Trash that have been in there more than a month or so. I never have to think about emptying the Trash. But I need to "touch" files I move to the Trash so that they don't get deleted at the wrong time.)

[ Reply to This | # ]
That's what this does
Authored by: leamanc on Feb 29, '08 05:54:27PM

He read the script, but is asking why use a script or function to replace a standard command when you can just type a little bit extra?

[ Reply to This | # ]
A shell function to make 'rm' move files to the trash
Authored by: spfolly on Feb 29, '08 09:19:55AM

A nice idea, but you haven't fully appreciated how the Trash works. This is fine for deleting stuff from your home folder, but if you use the Finder to delete stuff from, for example, a USB memory key, then the files get moved to a .Trashes folder on that volume. (And then a directory within that based on your UID.) The Trash folder viewable from the finder is a combination of ~/.Trash and .Trashes folders in mounted volumes.

[ Reply to This | # ]
A shell function to make 'rm' move files to the trash
Authored by: gpitts on Feb 29, '08 10:03:27AM

I've used something like this for years, but I call it 'dl' (for delete) so it's never confused with the real rm. Also, I move the files to <Trash>/yyyy-mm-dd-hh-mm-ss/ so I can easily empty the trash of files older than some amount. Over the years this has saved me from near disaster several times. But the last time I had to restore a file I just used time machine...

[ Reply to This | # ]
Authored by: garumph on Feb 29, '08 10:50:04AM

I have fired sysadmins who try this crap. NEVER redefine dangerous commands, create new ones and use those. I had a manufacturing line offline for a week because of things like this.

Use del or rmm or srm, anything, just not rm.

plus the fallout from the unexpected action for scripts could cause more damage.

[ Reply to This | # ]
Authored by: barko192 on Feb 29, '08 11:59:01AM

What about on a personal system?
If you are the only user, why shouldn't you be able to change commands as you see fit.
I don't want to change my rm, but if someone does and no one else has to use that computer, I don't see why they shouldn't be able to.

[ Reply to This | # ]
Mmmh.... what happens if another file with the same name is already in the Trash??
Authored by: germ on Feb 29, '08 01:56:24PM
What happens if another file with the same name is already in the Trash?
Authored by: marbx on Feb 29, '08 03:47:11PM

The function should work very similar to Finder -- if another file with the same name exists, it will append the current time to make the name unique. Say you delete "newfile," then delete a second file named "newfile" in a different folder. When you go to look in the Trash, you'll see "newfile" and "newfile 12-10-00" if you deleted the second "newfile" at ten minutes past noon.

[ Reply to This | # ]
A shell function to make 'rm' move files to the trash
Authored by: Dibbler on Feb 29, '08 02:24:16PM

Here's the problem. When you change the default behavior of existing commands, you're not only changing the configuration of one computer. You're changing your own behavior as a user. So whenever you're using someone else's computer (and don't assume that you won't) you constantly have to fight the habits formed by using altered commands on your own computer.

That's why you should only create new commands instead of redefining existing ones. If you accidently "rm wrongfile" on someone else's computer, you've just lost their data. However if you "trash wrongfile" you've only entered an unrecognized command.

[ Reply to This | # ]
A shell function to make 'rm' move files to the trash
Authored by: eexit on Mar 01, '08 07:55:12AM

I think it's useless. If you are scared to remove files accidentally, do not use command lines :)

[ Reply to This | # ]
"What about on a personal system?"
Authored by: pediddle on Mar 01, '08 08:54:10AM

Like garumph said -- the fallout for other scripts could still be disastrous. First of all, rm has many behaviors that differ slightly from just deleting files.

rm -R # recursive
rm -i # interactive
rm -f # forceful
rm -d # remove directories
rm -P # overwrite files ("secure")

Does this script obey ANY of these options? (And those are just the BSD options -- forget about it if you install the GNU version from DarwinPorts.) Any script that relies on these could fail disasterously, and WORSE, it could accidentally destroy your system.

Second, the low-level meaning of moving a file differs slightly from unlinking an inode (no, I don't understand exactly how it works). This could screw up anything that relies on that difference, too -- probably in subtle ways that could slowly corrupt your system over time.

Third, if you ever delete anything from another volume, the script actually COPIES files to ~/.Trash (and then deletes the originals) rather than moving them to the volume's own trash. Forget about it if you're trying to delete a "special" file (/dev/* entry, named FIFO, etc.).

Fourth, there are almost certainly other unintentional consequences that we haven't even considered. There always are. That's how software works (or more often doesn't, when you pull stupid stunts like this).

Any modern system is NEVER just a "personal" system. There are thousands of scripts running that are written by OTHER people. These other people are essentially using your computer every day.

[ Reply to This | # ]
Don't redefine standard commands
Authored by: hayne on Mar 01, '08 01:56:38PM

I agree with the other commenters above who have said that it is a very bad idea to name this as 'rm' (thus effectively replacing the standard 'rm' command).
If you want different behaviour from what 'rm' usually does, then you should use a different command. Naming this command 'trash' (as someone else suggested) seems like a good idea.

[ Reply to This | # ]
I want the exact opposite!
Authored by: jethro1138 on Mar 01, '08 11:08:03PM

I want the trash to just delete files! Or at least not ask me if I'm sure when I tell it to empty... pretty sure it USED to be able to do that in the previous version...

[ Reply to This | # ]
I want the exact opposite!
Authored by: mkutny on Mar 03, '08 11:56:14AM

Finder - Preferences - Advanced

[ Reply to This | # ]
A shell function to make 'rm' move files to the trash
Authored by: theduke on Mar 02, '08 12:23:49PM

I don't like the idea of reworking basic commands, and I don't like coming to depend on specialized functions that don't draw on my own private data (it becomes a pain to work on other people's computers when you don't have your little toolset handy).

What I do to avoid rm catastrophes is simple. I type the path first, look at it closely, then ^a back to the beginning of the line and type in the command.

If I'm really in doubt about what I'm doing, I'll type in ls instead of rm, just to be sure of what I'm going to hit.

[ Reply to This | # ]
sudo rm -f NOT MOVING files to the trash
Authored by: senortim on Jul 12, '08 02:31:32AM

I have several VERY stubborn files: sudo rm -f doesn't work, none of the commands in this thread work, *censored*tail and other utils don't work, and permissions say that I own the files. They are not on my startup volume, so the 'fool them with the shared dir' tricks don't work either.

These files are from the early days of Mac OS X (even including "darwin" in the names), and they've rested peacefully on my disk for years -- with the occasional attack from the newest version of whatever tool.

I'm sick of them, however. Can anyone give me a fool proof method for killing these files? (I'm still on Tiger, but upgrading to Leopard next week.)


[ Reply to This | # ]