15 Archiving Files As They re Removed


#15 Archiving Files As They're Removed

One of the most common problems that users have with Unix, in my experience, is that there is no way to recover a file or folder that has been accidentally removed. No Norton Unerase, no Mac OS X shareware utility, nada. Once you press RETURN after typing rm xyz , it's history.

A solution to this problem is to secretly and automatically archive files and directories to a .deleted-files archive. With some fancy footwork in a script, this can be made almost completely invisible to users.

The Code

 #!/bin/sh # newrm, a replacement for the existing rm command, provides a #   rudimentary unremove capability by creating and utilizing a new #   directory within the user's home directory. It can handle directories #   of content as well as individual files, and if the user specifies #   the -f flag files are removed and NOT archived. # Big Important Warning: You'll want a cron job or something similar to keep #   the trash directories tamed. Otherwise nothing will ever actually #   be deleted from the system and you'll run out of disk space!  mydir="$HOME/.deleted-files" realrm="/bin/rm"   copy="/bin/cp -R" if [ $# -eq 0 ] ; then # let 'rm' ouptut the usage error   exec $realrm # our shell is replaced by /bin/rm fi # Parse all options looking for '-f' flags="" while getopts "dfiPRrvW" opt do   case $opt in     f) exec $realrm "$@"      ;;  # exec lets us exit this script directly.     *) flags="$flags -$opt"   ;;  # other flags are for 'rm', not us   esac done shift $(($OPTIND - 1)) # Make sure that the $mydir exists if [ ! -d $mydir ] ; then   if [ ! -w $HOME ] ; then     echo " 
 #!/bin/sh # newrm, a replacement for the existing rm command, provides a # rudimentary unremove capability by creating and utilizing a new # directory within the user's home directory. It can handle directories # of content as well as individual files, and if the user specifies # the -f flag files are removed and NOT archived. # Big Important Warning: You'll want a cron job or something similar to keep # the trash directories tamed. Otherwise nothing will ever actually # be deleted from the system and you'll run out of disk space! mydir="$HOME/.deleted-files" realrm="/bin/rm" copy="/bin/cp -R" if [ $# -eq 0 ] ; then # let 'rm' ouptut the usage error exec $realrm # our shell is replaced by /bin/rm fi # Parse all options looking for '-f' flags="" while getopts "dfiPRrvW" opt do case $opt in f) exec $realrm "$@" ;; # exec lets us exit this script directly. *) flags="$flags -$opt" ;; # other flags are for 'rm', not us esac done shift $(($OPTIND - 1)) # Make sure that the $mydir exists if [ ! -d $mydir ] ; then if [ ! -w $HOME ] ; then echo "$0 failed: can't create $mydir in $HOME" >&2 exit 1 fi mkdir $mydir chmod 700 $mydir # a little bit of privacy, please fi for arg do newname="$mydir/$(date "+%S.%M.%H.%d.%m").$(basename "$arg")" if [ -f "$arg" ] ; then $copy "$arg" "$newname" elif [ -d "$arg" ] ; then $copy "$arg" "$newname" fi done exec $realrm $flags "$@" # our shell is replaced by realrm 
failed: can't create $mydir in $HOME" >&2 exit 1 fi mkdir $mydir chmod 700 $mydir # a little bit of privacy, please fi for arg do newname="$mydir/$(date "+%S.%M.%H.%d.%m").$(basename "$arg")" if [ -f "$arg" ] ; then $copy "$arg" "$newname" elif [ -d "$arg" ] ; then $copy "$arg" "$newname" fi done exec $realrm $flags "$@" # our shell is replaced by realrm

How It Works

There are a bunch of cool things to consider in this script, not the least of which is the significant effort it goes through to ensure that users aren't aware it exists. Notice that error messages are almost always generated by a call to realrm with whatever bad flags or file/directory names were specified. Also, the exec command, which replaces the current process with the new process specified, is a convenience. As soon as exec invokes realrm , it effectively exits the script, and we have the added side benefit of ensuring that the return code from the realrm process ( /bin/rm ) is given to the invoking shell, not lost.

Because this script secretly creates a directory in the user's home directory, it needs to ensure that the files therein aren't suddenly readable by others simply because of a badly set umask value. To accomplish this, the script uses chmod to ensure that the directory is set to read+write+execute for the user, and closed for everyone else.

Finally, the somewhat confusing file-naming convention uses basename to strip out any directory information from the file's path , and adds a time and date stamp to every deleted file in the form second.minute. hour .day.month.filename:

 newname="$mydir/$(date "+"%S.%M.%H.%d.%m").$(basename "$arg")" 

Notice the use of multiple $() elements in the same substitution. It's a bit complicated, perhaps, but helpful nonetheless. Remember, anything between $( and) is fed to a subshell, and the result of that command is what's substituted. Why bother with a timestamp? To enable our archive to store multiple files that could potentially have the same name prior to being deleted.

Running the Script

To install this script, simply add an alias, so that when you type rm you really get to this script, not to the /bin/rm command. A Bash/Ksh alias would look like this:

 alias rm=  yourpath  /newrm 

The Results

The results of running this script are subtle and hidden from immediate view, so let's keep an eye on the .deleted-files directory along the way:

 $  ls ~/.deleted-files  ls: /Users/taylor/.deleted-files/: No such file or directory $  newrm file-to-keep-forever  $  ls ~/.deleted-files/  51.36.16.25.03.file-to-keep-forever 

Exactly right. While the file was deleted from the local directory, a copy of it was secretly squirreled away to the .deleted-files directory, with an appropriate date/ time stamp to allow other deleted files with the same name to be stored in the same directory.




Wicked Cool Shell Scripts. 101 Scripts for Linux, Mac OS X, and Unix Systems
Wicked Cool Shell Scripts
ISBN: 1593270127
EAN: 2147483647
Year: 2004
Pages: 150
Authors: Dave Taylor

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net