May 1996
This is a shell script for Bash, called ‘rm_secure’. I use it as frontal for the rm command. It stores the deleted files in an archive in the user’s directory. A command-line option allows the user to view the content of this archive, and another option permits the restoration of the deleted files.
For example :
$ ls -l -rw-r--r-- 1 ccb users 22 May 26 10:33 important_file -rw-r--r-- 1 ccb users 23 May 26 10:34 not_important $ rm * (OOPS!) $ ls -l $ rm --viewtrash -rw-r--r-- 1 ccb users 22 May 26 10:35 1996 important_file -rw-r--r-- 1 ccb users 23 May 26 10:35 1996 not_important $ rm --restore important_file $ ls -l -rw-r--r-- 1 ccb users 22 May 26 10:35 important_file $ rm --viewtrash -rw-r--r-- 1 ccb users 23 May 26 10:35 1996 not_important $ rm --emptytrash $ rm --viewtrash $
Okay, it slows down a few the rm command. But it may also save hours of work lost due to a keystroke error…
There is the script ‘rm_secure’ :
#!/bin/bash # Configuration # the real 'rm' command bin_rm=/bin/rm # where archiving the files Archive=~/.rm_saved.tar # you may prefer something like : # Archive=/var/trash/$USER/saved_file.tar # (with write access permission on the directory) # global variables for the options Opt_recursive=0 Opt_no_secure=0 Opt_restore=0 Opt_rm="" # function for archiving a file or a directory save_file() { if [ $Opt_no_secure -ne 1 ] ; then # set date/time of deletion touch "$1" > /dev/null 2>&1 if [ -f $Archive ] ; then tar --delete -f "$Archive" "$1" > /dev/null 2>&1 tar -rf "$Archive" "$1" > /dev/null 2>&1 else tar -cf "$Archive" "$1" > /dev/null 2>&1 # r/w access only for the user chmod 600 "$Archive" fi fi } # function for restoring file or directory restore_file () { if [ -f $Archive ] ; then tar -xf "$Archive" "$1" > /dev/null 2>&1 tar --delete -f "$Archive" "$1" > /dev/null 2>&1 fi } # reading the command-line args while getopts "dfirRvns-:" opt ; do case $opt in d ) Opt_rm="$Opt_rm -d" ;; f ) Opt_rm="$Opt_rm -f" ;; i ) Opt_rm="$Opt_rm -i" ;; r | R ) Opt_recursive=1 Opt_rm="$Opt_rm -r" ;; v ) Opt_rm="$Opt_rm -v" ;; n ) Opt_no_secure=1 ;; s ) Option_restore=1 ;; - ) case $OPTARG in directory ) Opt_rm="$Opt_rm -d" ;; force ) Opt_rm="$Opt_rm -f" ;; interactive ) Opt_rm="$Opt_rm -i" ;; recursive ) Opt_recursive=1 Opt_rm="$Opt_rm -r" ;; help ) $bin_rm --help echo "(rm_secure)" echo " -n, --nosecure delete without backup" echo " --viewtrash list the saved files" echo " --emptytrash erase the saved files" echo " -s, --restore restore the specified files" exit 0 ;; version ) $bin_rm --version echo "(rm_secure 1.0)" exit 0 ;; verbose ) Opt_rm="$Opt_rm -v" ;; viewtrash ) if [ -f $Archive.gz ] ; then tar -tvzf $Archive.gz fi exit 0 ;; nosecure ) Opt_no_secure=1 ;; emptytrash ) if [ -f $Archive.gz ] ; then $bin_rm $Archive.gz fi exit 0 ;; restore ) Opt_restore=1 ;; * ) ;; esac ;; ? ) ;; esac done shift $(($OPTIND - 1)) gunzip $Archive.gz >; /dev/null 2>&1 # restoration ? if [ $Opt_restore -ne 0 ] ; then while [ -n "$1" ] ; do restore_file "$1" shift done exit 0 else while [ -n "$1" ] ; do if [ -d "$1" ] ; then # the directories are archived only with # the -r option if [ $Opt_recursive -ne 0 ] ; then save_file "$1" fi $bin_rm $Opt_rm $1 elif [ -e "$1" ] ; then # existing file save_file "$1" $bin_rm $Opt_rm $1 else # let 'rm' give his error message $bin_rm $1 fi shift done fi nice gzip $Archive > /dev/null 2>&1 & # -- end of script --
Place it in /usr/bin or /usr/local/bin then insert a ligne :
alias rm='/usr/local/bin/rm_secure'
in /etc/profile, so this script will be called by Bash in the place of the true rm command.
You can use the ‘–nosecure’ or ‘-n’ option to delete a file without archiving it. This is useful when you decide to erase huge amount of files in recursive directories (for example a package you have tested but find uninteresting).
I use a cron job to deleted the archived files every day (running as root job).
# crontab -l [ …] 00 04 * * * /usr/local/bin/empty_trash #
Here is the ’empty_trash’ script :
#! /bin/bash for user in /home/* ; do /bin/rm $user/.rm_saved.tar.gz done /bin/rm /root/.rm_saved.tar.gz # -- end of script --
Maybe you can prefer something like :
trap '/bin/rm ~/.rm_saved.tar.gz EXIT
in /etc/profile, which erase the archive each time the user exits the shell. (I’ve not fully tested this)
Obviously this tips doesn’t secure the deletion of files or directories by a file-manager, but I find it quite usefull, especially when doing administrative jobs as root (‘rm tmp/ *’ in place of ‘rm tmp/*’ …)
2 Réponses
URL de trackback pour cette page
It seems cool but i think there is a mistake on the definition of this variable.
OPTIND is not declared.
shift $(($OPTIND – 1))
OPTIND
is a special variable for Bash. Here’s an excerpt of the bash man page :