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/*’ …)
URL de trackback pour cette page