Script bash shell - Making an alternative trashcan

605 views Asked by At

I've made this script, but I have difficulties to write the code for this situation: in the trashcan there should be no file with the same name; in which case they should be renamed.

How can I solve?

Here is my code:

#!/bin/bash

help() {
    echo "Options:"
    echo "\"safe-rm pathname\" to delete, where the pathname can be absolute or relative"
echo "\"safe-rm --recover original pathname\" (including the /) to recover and restore a file or a directory in the original position"
    echo "\"safe-rm --list\" to lists the trashcan's content"
    echo "\"safe-rm --search\" to search a file in the trashcan"
    echo "\"safe-rm --delete-older-than\" to delete files older than certain days"
}

delete() {
    if [ ${PARAM1:0:1} = "/" ]; then
        echo "You have insert an absolute pathname"
        mkdir -p $(dirname $TRASH$PARAM1)
        mv $PARAM1 $TRASH$PARAM1
    else
        echo "You have insert a relative pathname"
        mkdir -p $(dirname $TRASH$(pwd)/$PARAM1)
        mv $PARAM1 $TRASH$(pwd)/$PARAM1
    fi
}

readonly TRASH=$HOME/.Trash;
readonly PARAM1=$1;
readonly PARAM2=$2;

mkdir -p $TRASH;

case "$PARAM1" in
    "")
        help    
    ;;
    --list)
        echo "Trashcan's content"
        cd $TRASH
        find *
    ;;
    --delete-older-than)
        echo "Delete the files older than $PARAM2 days"
        find $TRASH -mtime +$PARAM2 | xargs rm -rf
    ;;
    --search)
        echo "Search $PARAM2 among the trashcan's files"
        cd $TRASH
        find -name *$PARAM2*
    ;;
    --recover)
        echo "Recover the file/directory in the original position"
        mkdir -p $(dirname $PARAM2)
        mv $TRASH$PARAM2 $PARAM2
    ;;
    *) 
        echo "Security delete a file/directory"
        delete
    ;;
esac

exit 0
3

There are 3 answers

0
Aleks-Daniel Jakimenko-A. On

Quick and dirty solution:

if [[ -f $TRASH$PARAM ]]; then
    mv "$PARAM1" "$TRASH$PARAM$RANDOM$RANDOM" # file exists
else
    mv "$PARAM1" "$TRASH$PARAM" # ok, it is fine, file does not exist
fi

Also please note that you have to quote every variable in your script when it is passed as a parameter.

  • if [ ${PARAM1:0:1} = "/" ]; then must be changed to if [ "${PARAM1:0:1}" = "/" ]; then or even better if [[ ${PARAM1:0:1} = "/" ]]; then
  • mkdir -p $(dirname $TRASH$PARAM1) to mkdir -p "$(dirname "$TRASH$PARAM1")"
    And so on...
0
konsolebox On

Consider generating a trailing sum like sha1sum on your files when they are stored on the the trash can to prevent having conflicts with similar files. e.g.

$HOME/.Trash/home/user/same/path/same_name.9ce1f394b955306f7c450cbf0d96d2f17f6a1394
$HOME/.Trash/home/user/same/path/same_name.b0dc31b1919c02932892b59d0c0e365cd75629c6

When restoring those files you just have removed the sum like

/home/user/same/path/same_name

The solution could also prevent duplicates of truly the same files for the probable uniqueness of what sums could do.

If you trust sums enough you could also opt to not store the directories in the trash. Just their signatures with an extra info file on it like:

$HOME/.Trash/same_name.9ce1f394b955306f7c450cbf0d96d2f17f6a1394
$HOME/.Trash/same_name.9ce1f394b955306f7c450cbf0d96d2f17f6a1394.info

Where info contains the absolute path of the directory where the file is located.

/home/user/same/path/

You could even add other attributes on it like directory permissions, etc.

[File]
/home/user/same/path/same_name

[Attributes]
/home[ TAB ]USER:GROUP[ TAB ]0755
/home/user[ TAB ]USER:GROUP[ TAB ]0755
/home/user/same[ TAB ]USER:GROUP[ TAB ]0755
/home/user/same/path[ TAB ]USER:GROUP[ TAB ]0755
/home/user/same/path/same_name[ TAB ]USER:GROUP[ TAB ]0644

Basically sums are just concepts but you could add more tricks on your own base on it to make file existence in trash a little more certain to be unique, only that you have to consider that it could no longer prevent files with that are really the same to exist as two entries which could have been not necessary.

Also of course on your script if you want to support filenames with spaces and likes, always place your variables inside double-quotes to prevent those from word splitting which means they would could later be interpreted as two or more arguments to the command causing syntax error to the command or unexpected results in which some may be irrevocable.

do something "$var" "${etc}xyz"
0
user447607 On

Actually, I wrote that back in 2010. Now there is a trash-cli package for Ubuntu.

http://wiki.linuxquestions.org/wiki/Scripting#Command_Line_Trash_Can