Ask Different is a question and answer site for power users of Apple hardware and software. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I do a lot of terminal work, and today had the experience of typing

rm fileInQuestion.txt

Before finding out that I did actually need fileInQuestion.txt. If I'd deleted in the GUI then I would have just gotten it out of the Trash. I'd like to know if it's possible to overload 'rm' in the Terminal in such a way that it sends the file/files to the Trash on the way out.

share|improve this question
There are programs that can recover deleted files (as long as those sectors on the hard drive are not overwritten in the mean time!). When this happens, you should use one of those... – iconoclast Jun 6 '14 at 13:54
Also see for googlers looking for ubuntu/debian/linux file trashing. – ThorSummoner Jul 16 '15 at 19:48

11 Answers 11

up vote 74 down vote accepted

I wouldn't advise aliasing rm to mv as you might get in the habit of rm not permanently deleting files and then run into issues on other computers or under other user accounts when it does permanently delete.

I wrote a set of bash scripts that add more Mac OS X-like command line tools (in addition to a number of the built-in ones like open, pbcopy, pbpaste, etc.), most importantly trash. My version of trash will do all the correct things that aliasing rm won't (and hopefully nothing bad, but I've been using it on my own Macs for a few years now without any lost data), including: renaming the file like Finder does if a file with the same name already exists, putting files in the correct Trash folder on external volumes; it also has some added niceties, like: it attempts to use AppleScript when available so you get the nice trash sound and such (but doesn't require it so you can still use it via SSH when no user is logged in), it can give you Trash size across all volumes.

You can grab my tools-osx suite from my site or the latest and greatest version from the GitHub repository.

There's also a trash command developed by Ali Rantakari, but I haven't tested that one myself.

share|improve this answer
Excellent answer, much better than mine! – user1256923 May 9 '12 at 15:25
I've used trash by Rantakari for quite a while and can really vouch for it. It is compiled Objective-C and cleverly uses standard filesystem APIs and, should it fail (ie. user doesn't have sufficient rights), it calls Finder to trash the files (effectively prompting for authentication). You can read more info of trash from – koiyu May 9 '12 at 16:39
trash is also available via the brew package manager. just use: brew install trash. – Landon Kuhn Jan 22 '13 at 23:03
@landon9720 Good point. And, to clarify for others, the trash command available through Homebrew is Alai Rantakari's (see the brew formula)‌​. – morgant Jan 24 '13 at 0:36
@landon9720 love me some homebrew trash! – the0ther Feb 6 '14 at 16:19

The trash command line tool can be installed via brew install trash.

It allows you to restore trashed files via command line or the Finder.

share|improve this answer
What an elegant solution! – ShadowGiraffe May 18 '15 at 0:35
Also available in macports: port install trash – holocronweaver Jul 19 '15 at 2:57
every time I try to brew install trash, I get this: – Ben C. R. Leggiero Oct 30 '15 at 14:32
@BenC.R.Leggiero I would take that issue over to Did you brew update first? Works good on my end. – Paul Wenzel Nov 12 '15 at 19:27
@PaulWenzel yes, and it seems to update just fine. I'll post an issue. – Ben C. R. Leggiero Nov 12 '15 at 19:37

I found a pretty nice code that can be added at the end of user's batch profile and causes rm to move the files to the trash each time it is run.

nano ~/.bash_profile

#... append at the end
function rm () {
  local path
  for path in "$@"; do
    # ignore any arguments
    if [[ "$path" = -* ]]; then :
      # remove trailing slash
      local mindtrailingslash=${path%/}
      # remove preceding directory path
      local dst=${mindtrailingslash##*/}
      # append the time if necessary
      while [ -e ~/.Trash/"$dst" ]; do
        dst="`expr "$dst" : '\(.*\)\.[^.]*'` `date +%H-%M-%S`.`expr "$dst" : '.*\.\([^.]*\)'`"
      mv "$path" ~/.Trash/"$dst"


share|improve this answer
This is v clever but I still wouldn't recommend this. It's clever because its in the bash profile for the user and so only the user can execute this version of the function by typing it in, scripts that rely on rm will still call the original. But I wouldn't recommend doing this because the user will get used to rm acting in this way when it doesn't on other machines. I'm going to use this but rename the function "trash" – Matt Parkins Feb 21 '14 at 10:06
I am using the same function with two changes: ① I corrected a bug in the function that causes any folder to be renamed to the timestamp, if it has been tab-completed to include a trailing slash: This requires the following changes: Replacing the line local dst=${path##*/} with local dst=${mindtrailingslash##*/} and inserting another line just before that one that says local mindtrailingslash=${path%/}. ② I use the name function rr. Like this, it does not interefere with plain rm, but the name is similarly short and fast to type (any other name would do). – mach Apr 7 '15 at 14:56
Change the name of rm() to rmt() - This way you can still use the rm command when you want. I think of rmt in my head as remove to trash :D – James111 Jan 29 at 6:09

I have an executable called rem somewhere in my $PATH with the following contents:

#!/usr/bin/env python
import os
import sys
if len(sys.argv) > 1:
    for arg in sys.argv[1:]:
        if os.path.exists(arg):
            os.system('osascript -e \'tell app "Finder" '
                      + 'to move the POSIX file "'
                      + os.path.abspath(arg) + '" to trash\'')
            print "Error:", os.path.abspath(arg), "does not exist"
    print "usage: rem file(s)"
    print "       move file(s) to Trash"

It behaves in exactly the same way as deleting from the Finder. (See blog post here.)

share|improve this answer
This should have more points IMO. Because it is AppleScript it uses the actual trash process to move the file to trash, which means it will behave exactly the same. Shame a one-liner was not provided however. – mxcl Mar 2 at 18:07
Well, someone downvoted it on Oct 31 '15 at 10:26 - at precisely the same time that someone else was posting an answer to this question! – Anthony Smith Mar 3 at 9:58

a modern approach using swift

// main.swift
// recycle
// usage: recycle <files or directories to throw out>

import Foundation
import AppKit

var args = NSProcessInfo.processInfo().arguments
args.removeAtIndex(0) // first item in list is the program itself

var w = NSWorkspace.sharedWorkspace()
var fm = NSFileManager.defaultManager()

for arg in args {
    let path = arg.stringByStandardizingPath;
    let file = path.lastPathComponent
    let source = path.stringByDeletingLastPathComponent

        destination: "",
        files: [file],
        tag: nil)
share|improve this answer
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – jherran Mar 20 '15 at 5:07
@jherran thanks for the reminder, I added a code segment – slf Mar 20 '15 at 11:43
This is my preferred answer because it uses the same underlying logic and APIs as the GUI. – Jason R. Coombs Oct 7 '15 at 14:16
Now if only there were a Python version that avoided the need for a 3MB binary to make one system call. – Jason R. Coombs Oct 7 '15 at 14:18

While it is possible to make rm move files to Trash instead of removing them, I would advise against bringing the mindset of the safety net of graphical user interfaces to the UNIX shell. There are many ways to do serious damage using the terminal. The best advise IMHO is to simply think twice before hitting the enter key in a shell window.

If you want rm to remind you that you are about to delete a file consider using the following alias (for /bin/bash put this line in .bashrc in your home directory):

alias rm "rm -i"

This will make rm request confirmation before attempting to remove each file.

If you have TimeMachine running (I hope so!) you can always get your file from backup. This way you can lose at most one hour of work. Which is bad enough, of course. So think again before pressing that enter key!

share|improve this answer
Don't do it! Installer scripts may use rm and hang with the alias rm -i. – Old Pro May 9 '12 at 20:43
@OldPro: .bashrc is only executed if the shell is interactive. Check the man page! – Mackie Messer May 9 '12 at 21:07
i would advise against removing safety nets, or admonishing others to do so. – the0ther Feb 6 '14 at 16:18

Check out trash-cli. It works cross-platform, no trash sound, and supports Put Back.

You can install it with (requires Node.js):

$ npm install --global trash-cli

Alternatively, if you don't want to use Node.js, you can install the native binary osx-trash manually.

share|improve this answer

Properly trashing stuff (so that it is definitely recoverable) is trickier than simply a mv to ~/.Trash.

osx-trash might be what you're looking for. (Caveat emptor - I haven't tried it, and cannot vouch for how safe it is.)

share|improve this answer

In your .bashrc (or wherever you keep the parameters for your shell), try adding an alias that changes the behaviour of rm to moving stuff to ~/.Trash, as in:

alias rm='move/to/.Trash'

This alias if far from trivial to implement (at least for me) though, because the use of mv (the prime candidate to use for this job) is

mv file where

so having an alias that puts the 'where' part in front of the file to be moved might be pretty sketchy. I'll look into it an might get more substantial advice.

EDIT: I just tried to add the following to my .bashrc, and it works:

function trash { mv "$@" ~/.Trash ; }

It is much more primitive than other suggestions, but you avoid installing new stuff.

share|improve this answer
Aliasing rm to anything is dangerous because it may break installer scripts. I learned this the hard way when I aliased rm to rm -i and had installs hang. – Old Pro May 9 '12 at 20:42
@Old Pro, that's the alias I use for rm in all my computers, from day 0, and I never had issues because of it. Care to give an example? – user1256923 May 9 '12 at 20:56
@OldPro: .bashrc is only used for interactive shells. If you run ./ a new process is started and the alias will not be active. However, if you run . your current process will execute the installer and the alias is active. RTFM... – Mackie Messer May 9 '12 at 21:21
Then the installer was running an interactive shell and therefore was seriously broken. One broken installer is hardly enough reason to advise against shell aliases in general. YMMV – Mackie Messer May 9 '12 at 21:51
However, it is good advice to not alias the rm command, as morgant said, because you'll become comfortable with rm not actually removing files and then might accidentally delete something on a system where no such alias has been added. Also, moving a file to the trash is not as simple as just mv {} ~/.Trash. If the file is on a separate volume, for example, this will copy the file to your home directory and delete the original. – Josh May 30 '13 at 21:46

I have simply put this script

application=$(basename "$0")
if [ "$#" == 0 ]; then
    echo "Usage: $application path [paths...]"
    exit 1
while (( "$#" )); do
    if [ -e "$1" ]; then
        src=$(basename "$1")
        while [ -e "$trashdir/$dst" ]; do
            dst=$src+`date +%H-%M-%S`
        mv -f "$1" "$trashdir/$dst"
        echo "$1" does not exist.

in ~/bin/trash, made it excutable chmod +x ~/bin/trash, and added the following line to ~/.bash_profile


Then one can use it as

$ trash broken.js olddir cleanup.*
share|improve this answer

A simple function could let you trash files by moving them to the user's .Trash folder:

trash() {
   mv $1 ~/.Trash
share|improve this answer
? why a negative vote? this would be my thought as well.. – CousinCocaine Aug 1 '14 at 14:25
You probably need $* instead of $1, but then you would end up with the same answer as mv "$@" ~/.Trash. Why people vote it negatively, check the comments from the other answer. – kenorb May 6 '15 at 21:36
Be careful with this alias; this works if you only have one partition or drive. If you're working on a second volume or network share, this will actually copy the file to your home directory's trash, which is probably not what you wanted to do! – jmk May 28 '15 at 10:46

Your Answer


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.