Rm alternative

From UVA Linux Users Group

Jump to: navigation, search

Contents

Intro

Accidentally removing files with rm is a bummer, and recovering files from backups can take some time, if they exist at all.

This guide is intended to illustrate the possibilities of a simple alternative to the rm command. This alternative aims to prevent the accidental removal of files, without being overly complex or confusing. The example script moves files to a user specified TRASH folder at the root of the mount point, instead of deleting the files. Suggestions are made for automatic trash removal as well as integration with flexbackup.

The Script

Charateristics

  • Trash stored mount point of origin: This script will copy the file(s) passed to a trashbin folder located on the mount point of which the file(s) to delete exist. This feature prevents the moving of all trash to a central location, which generates a lot of unnecessary disk usage/traffic.
  • Different trashbins per mount point: Each mount point can have a custom trashbin, which may be desirable due to permissions.
  • Different trashbins per user: Each user can have their own trashbins. This way users can delete it how they see fit.
  • Strip options : This script will strip all options passed to it so that it can be used as a replacement for rm.


You can edit the TRASH variable to whatever you like. For example, TRASH is this script should is set to .Trash-$USER, so that each user can have their own trashbins. The TRASH variable can can be set per mount point, MNT, as shown below.


File: /usr/local/bin/del
#!/bin/bash
# Description:  Replacement for rm. It moves files to trashbin directories
#               which are stored on each mount point. trashbins can be different 
#               for each mountpoint. All trashbins are logged in TRASHBIN_LOG.
## TODO:         fix the mv command to check for existance of same-named directories.

TRASH=.Trash-$USER
TRASHBIN_LOG=~/.trashbins


## this is needed to reset TRASH variable for each argument 
TRASH_DIR=$TRASH

## loop through all variables that are not options, and mv each to a trashbin. 
while [ ! -z $1 ]; do
    if [ ${1:0:1} = "-" ]; then
            shift
    else

    ## reset trash variable.
    ## this is important for deleteing multiple files
    TRASH=$TRASH_DIR

    ## Get the Current mount point
    MNT=`df "$1" | grep / | awk '{ for (i=6;i<=NF;i++) { printf " " $i } printf "\n"  }'`
    MNT=${MNT:1}

    ## Trash bins may be relocated depending on mount point. 
    ## you may change these to your liking. 
    ## TODO: this should be easier to edit, using variables
    if [ "$MNT" = "/" ]; then
        TRASH=/tmp/"$TRASH"
    elif [ "$MNT" = "/home" ]; then
        TRASH=/home/$USER/"$TRASH"
    else
        TRASH="$MNT"/"$TRASH"
    fi

    ## Test for the TRASH folder
    if [ ! -d "$TRASH" ]; then
        if mkdir "$TRASH" ; then
            chmod u+rw "$TRASH"
            echo creating $TRASH
            echo writing info to  ~/.trashbins
            echo $TRASH >> ~/.trashbins
        else
            echo ERROR: cannot create $TRASH
            exit 1;
        fi
    fi


    ## Move each file to the trash, after updating time-stamp.
         touch "$1"  
         mv -v "$1" "$TRASH/"
    shift
    fi
done


Make the script executable

# chmod +x /usr/local/bin/del

Now if you "delete" files with del they will be moved to a $TRASH directory at the root of the mount point that the files originated from.

Maintence and Backups

Remember, you have to clean up these trashbins. If you used different TRASH variables for different mount points, as shown in the script, you may like to reference the TRASHBIN_LOG variable in a cron file. for example you could put the following in /etc/cron.daily to empty trash that is a week old, every day.


File: /etc/cron.daily/clean_trash.sh
#!/bin/bash
#
#   Empty the contents in directories listed in ~/.trashbins
#
for i in `cat ~/.trashbins`
    do
    if  [ `ls -a1  $i | wc -l ` -gt 2 ] ; then
            find "$i" -mtime +7 -delete
    fi 
done        


If you would like to exclude the trashbins from your backups, then you could set some pruning options to match the bins. for example if you use flexbackup you can add a prune like like so.


File: /etc/flexbackup.conf
...
$prune{'/'} = 'tmp';
$prune{'/home'} = ' .*/.Trash.*';
...

Replace RM

File: ~/.bash_profile

...

alias rm="/usr/local/bin/del"
alias rm.old="/bin/rm"
...
Personal tools