|
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/*' …)
|