A shell function to make 'rm' move files to the trash

Feb 29, '08 07:30:02AM

Contributed by: marbx

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

Comments (28)

Mac OS X Hints