This is a script (function) to be added to a bashrc. The purpose is to not actually remove files, but rather to send them to a trash folder for safe keeping. I was tired of deleting important files. Because files may have the same name, I chose to create subdirectories with the date and file name on them, for easy access and to prevent conflicts.
Thoughts? Improvements I could make? This is my first BASH script function, and I'd love to make it a standard part of my computers, so I want to make it good first!
function rm {
PREFIX="~/.Trash";
for FILE in "$@" ; do
STARDATE=`date +%Y%m%d-%H%M`;
PLACE="${STARDATE}-${FILE}" ;
mkdir -p "${PREFIX}/${PLACE}";
mv $FILE $PREFIX/$PLACE/$FILE ;
echo "${FILE} moved to ${PREFIX}/${PLACE}" ;
done
}
2 Answers 2
Interesting idea! I propose to rewrite the script this way:
rm() {
TRASH=~/.Trash
for FILE; do
DATE=$(date +%Y%m%d-%H%M)
TARGETDIR="$TRASH/$DATE-$FILE"
mkdir -p "$TARGETDIR"
mv -v "$FILE" "$TARGETDIR/"
done
}
What I changed and why:
for i; do
is equivalent tofor i in "$@"; do
but shorter- In
PREFIX="~/.Trash"
, the~
does NOT expand to your home directory, so I believe this is a bug. And since there's nothing to quote in.Trash
either, you can just writePREFIX=~/.Trash
without any quoting - Instead of an
echo
after themv
, you can use the-v
flag to makemv
more verbose and speak for itself - Correctly quoted everywhere it's necessary
- Changed the deprecated
`cmd`
style command substitution to the new recommended$(cmd)
style - Renamed variables to be more intuitive, though I know this is subjective:
- PREFIX to TRASH, to be more specific and clear
- STARDATE to DATE, because I don't know what is "STAR" and DATE alone is already pretty clear
- combined PREFIX + PLACE to TARGETDIR to reduce duplication
- Changed
function rm {
torm() {
, because this seems to be the preferred way to declare functions in bash - Removed all the trailing
;
, you don't need them - Use
$VARNAME
instead of${VARNAME}
, because I find that easier to read, but do as you like
Personally I would rename rm()
to trash()
,
because most of the time I certainly don't want to backup everything,
especially when deleting directories.
trash
also seems intuitive.
By the way, this is a great site to check your Bash scripts for common mistakes:
You should realize that this is not a drop-in replacement for /bin/rm
. For example, this function won't handle options such as -f
correctly.
You double-quoted several variable expansions, but you must make it a religious habit to always double-quote all such expansions. Otherwise, special characters in filenames will break your script in nasty ways.
Error handling is poor. You'll echo a confirmation even when mv
fails. Therefore, you should join commands nontrivial with semicolons, but with &&
. Also, errors should go to standard error instead of standard out, so use echo "..." >&2
.
$PREFIX/$PLACE/$FILE
is not quoted. Also, why do you use${foo}
instead of just$foo
? \$\endgroup\$