A safe rm

October 27, 2009

Here is a script that implements a Windows style ‘Recycle Bin’ delete function. Similarly like Windows delete, it moves deleted files/directories to a temporary directory (default: $HOME/.tmp). After a file is moved to the tmp directory and has not been accessed for N days, it is permanently deleted the next time the rm command is run (think of this as an automated ’empty recycle bin’ function). It implements all the ‘rm’ options making it an ideal replacement for the /bin/rm command in interactive use.

Example usage:
  $ alias rm=$HOME/bin/rm

#! /bin/sh
#  Synopsis:     rm [-fir] file ...
#  Description:  A Safe rm (move file(s) to a tmp directory for later deletion).  Files in
#                the tmp directory that have not been accessed in N days are permantly deleted 
#                the next time the rm command is run.  
#                Options: -f  (force) Run "/bin/rm" instead of moving files to the tmpdir
#                         -i  interactive mode
#                         -r  move (recursively) a directory tree to the tmp directory
#                Caveat: mv fails if the filename matches a directory name in the $tmpdir directory.

#set -x
while getopts fir opt; do
        case $opt in
        f) force="-f";;
        i) interactive="-i";;
        r) recursive="-r";;
        \?) exit 1;;
shift `expr $OPTIND - 1`

if [ "$force" ]; then                            # Run /bin/rm if '-f' is specified!
	/bin/rm -f $interactive $recursive "$@";  # This is useful in shell functions
	exit $?                                   # when you want the real rm executable

for file; do
        if [ -n "$interactive" ]; then
                echo -n "remove '${file}'? "
                read yn
                if [ "$yn" != "Y" -a "$yn" != "y" ]; then
        if [ -d "$file" ]; then
                if [ -n "$recursive" ]; then
                        mv -f "$file" "$tmpdir" || retcode=2
                        echo "$0: cannot remove '$file': Is a directory"
        bf=`basename "$file"`
        mv -f "$file" "$tmpdir"
        touch "$tmpdir/$bf";  # For post cleanup, $file will be deleted N days from today

# Prolog: Clean up files, permanently delete files after atime days have elapsed
{ /bin/find "$tmpdir" -type f -atime +7 -exec /bin/rm '{}' \;
  /bin/find "$tmpdir" -mindepth 1 -type d -exec rmdir '{}' \; 2>/dev/null 
} &

exit ${retcode:-0}