patternbashMinor
Bash script to send to recycle bin or trash
Viewed 0 times
scriptrecyclebintrashsendbash
Problem
This is a script that emulates a recycle bin in the CLI.
You can undo your last changes and delete files
This is my first bash script so don't hesitate to bash me. Thank you for taking a look.
``
EMPTY=0
UNDOFILE=
while getopts “hvnrsued:” OPTION
do
case $OPTION in
h)
usage
exit 0
;;
v)
VERBOSE=1
;;
n)
DRY=1
;;
r)
RESTORE=1
;;
u)
UNDO=1
;;
d)
RBIN=$OPTARG
;;
e)
EMPTY=1
;;
s)
ERRORSTOP=1
;;
?)
echo "Invalid option: -$OPTARG" >&2
usage
exit 1
;;
esac
done
#setting the undo file name, will be ~/.recycle-log by default
UNDOFILE=$TROOT/$RBIN"-log"
#setting full path for the recycle bin dir
RBIN="$TROOT/$RBIN"
if [ "$VERBOSE" = 1 ]; then
echo "recycle dir: $RBIN"
echo "current dir: $CURR"
fi
# creating the recycle bin dir if it does not exist
test -d "$RBIN" || mkdir -p "$RBIN"
if [ ! -d "$RBIN" ]; then
echo "could not create the directory $RBIN" >&2
exit 1
fi
# if -u was passed, undo and exit
if [ "$UNDO" = 1 ]; then
if [ -f "$UNDOFILE" ]; then
source $UNDOFILE
rm $UNDOFILE
echo "undone" >&2
exit 0
else
echo "no undo file found, cannot undo" >&2
exit 1
fi
fi
# resetting undo file for changes to come
if [ -f "$UNDOFILE" ]; then
rm $UNDOFILE
fi
shift $(( OPTIND - 1 ))
# if -e or -u were passed, no arguments is ok
# if not, then the used should provide at least
# one filename
if [ "$EMPTY" = 0 ]; then
if [ -z
You can undo your last changes and delete files
This is my first bash script so don't hesitate to bash me. Thank you for taking a look.
``
#! /bin/bash
usage(){
cat specify the recycle directory
(defaults to '.recycle' in your ~)
All other options are ignored when moving files. When removing
permanently, these options are passed to /bin/rm
EOF
}
FILES=""
VERBOSE=0
DRY=0
RESTORE=0
ERRORSTOP=0
TROOT="$HOME"
UNDO=0
RBIN=".recycle"
CURR=pwd`EMPTY=0
UNDOFILE=
while getopts “hvnrsued:” OPTION
do
case $OPTION in
h)
usage
exit 0
;;
v)
VERBOSE=1
;;
n)
DRY=1
;;
r)
RESTORE=1
;;
u)
UNDO=1
;;
d)
RBIN=$OPTARG
;;
e)
EMPTY=1
;;
s)
ERRORSTOP=1
;;
?)
echo "Invalid option: -$OPTARG" >&2
usage
exit 1
;;
esac
done
#setting the undo file name, will be ~/.recycle-log by default
UNDOFILE=$TROOT/$RBIN"-log"
#setting full path for the recycle bin dir
RBIN="$TROOT/$RBIN"
if [ "$VERBOSE" = 1 ]; then
echo "recycle dir: $RBIN"
echo "current dir: $CURR"
fi
# creating the recycle bin dir if it does not exist
test -d "$RBIN" || mkdir -p "$RBIN"
if [ ! -d "$RBIN" ]; then
echo "could not create the directory $RBIN" >&2
exit 1
fi
# if -u was passed, undo and exit
if [ "$UNDO" = 1 ]; then
if [ -f "$UNDOFILE" ]; then
source $UNDOFILE
rm $UNDOFILE
echo "undone" >&2
exit 0
else
echo "no undo file found, cannot undo" >&2
exit 1
fi
fi
# resetting undo file for changes to come
if [ -f "$UNDOFILE" ]; then
rm $UNDOFILE
fi
shift $(( OPTIND - 1 ))
# if -e or -u were passed, no arguments is ok
# if not, then the used should provide at least
# one filename
if [ "$EMPTY" = 0 ]; then
if [ -z
Solution
- You don't need a space in the current shebang line. Anyway, Greg's wiki and others recommend
#!/usr/bin/env bash(for portability, but I can't find a reference at the moment).
-
Any command substitutions should use
"$(foo)" rather than `foo. That way, you actually get what the command returns (except for trailing newlines) rather than a whitespace-clobbered version. For example, CURR="$(pwd)", or even better:
CURR="$(pwd; echo x)"
CURR="${CURR%x}"
- Don't use actual opening and closing quotation marks (
“hvnrsued:”). This type of quotes are just regular characters in Bash, so it's as if you had added a -“ and -” option. More about quotes.
- Some lines are not indented properly. Incorrect indentation makes the code hard to read, and in the worst case can introduce errors because of misunderstandings of context.
-
Use the safe version of all calls which support it: command --option1 --option2 -- "$file1" "$file2". The double dashes separate options from filenames in most *nix commands, to avoid interpretation of filenames as options, or, in the worst case, acting on the wrong file. Other commands have special flags (-e, --regex in grep) to prefix other options to avoid treating the second option as another flag. Compare (untested)
printf %s -foo | grep -foo # No such file oo
with
printf %s -foo | grep -e -foo
-
echo is one of those unfortunate commands which don't have such an option. Use printf if you don't know what the input will be. Compare (untested)
string=-escape
echo "$string" # No such option -s
with
printf %s "$string"
-
Create lots of test cases. This is such a dangerous script that you'd better have some proof that complex file names created by accident or malicious users don't have an opportunity to wreak havoc. I can thoroughly recommend shunit2, which is even in the Ubuntu repositories. Example tests.
- You should add
set -o errexit -o noclobber -o nounset -o pipefail at the beginning of the file to ensure stricter error checking. Only re-enable clobbering for the smallest possible code block (i.e., the single line where you use redirection to file) if necessary.
-
Declare read-only variables as such (help readonly, help declare) to avoid accidental modification. This should be done separately from assignment - If you do it together (declare -r foo="$(false)"`), you'll find that the exit code of the command substitution is lost. Comparedeclare -r foo="$(false)"
echo $?with
bar="$(false)"
echo $?
declare -r bar
echo $?Code Snippets
CURR="$(pwd; echo x)"
CURR="${CURR%x}"printf %s -foo | grep -foo # No such file ooprintf %s -foo | grep -e -foostring=-escape
echo "$string" # No such option -sprintf %s "$string"Context
StackExchange Code Review Q#10768, answer score: 5
Revisions (0)
No revisions yet.