How to move files to trash from command line?
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.
Solution 1:
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.
Solution 2:
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.
Solution 3:
I have an executable called rem
somewhere in my $PATH
with the following contents:
EDIT: code below is a revised and improved version in collaboration with Dave Abrahams:
#!/usr/bin/env python
import os
import sys
import subprocess
if len(sys.argv) > 1:
files = []
for arg in sys.argv[1:]:
if os.path.exists(arg):
p = os.path.abspath(arg).replace('\\', '\\\\').replace('"', '\\"')
files.append('the POSIX file "' + p + '"')
else:
sys.stderr.write(
"%s: %s: No such file or directory\n" % (sys.argv[0], arg))
if len(files) > 0:
cmd = ['osascript', '-e',
'tell app "Finder" to move {' + ', '.join(files) + '} to trash']
r = subprocess.call(cmd, stdout=open(os.devnull, 'w'))
sys.exit(r if len(files) == len(sys.argv[1:]) else 1)
else:
sys.stderr.write(
'usage: %s file(s)\n'
' move file(s) to Trash\n' % os.path.basename(sys.argv[0]))
sys.exit(64) # matches what rm does on my system
It behaves in exactly the same way as deleting from the Finder. (See blog post here.)
Solution 4:
Use the terminal command osascript, the AppleScript interpreter.
osascript -e "tell application \"Finder\" to delete POSIX file \"${PWD}/${InputFile}\""
This tells AppleScript to tell Finder to send the file to trash.
PWD is needed for relative file paths, as AppleScript does not handle that well.