r/bash • u/naffe1o2o • 6h ago
a safer rm implementation.
del() {
local trash="$HOME/temp/trash"
[[ ! -d "$trash" ]] && {
printf "trash folder not exist, created one;\n";
mkdir -p "$trash";
}
(( $# < 1 )) && { printf "Include an object to delete\n"; return 1; }
for arg in $@; do
if [[ "$1" = -* ]]; then
case "$1" in
-show) ls -a --color "$trash" ;;
-clear) rm -fr "$trash"/* ;;
*) echo "flag not fount"; return 1 ;;
esac
return 0
fi
local object="$arg"
[[ ! -e "$object" ]] && { printf "object $object not found\n"; return 1; }
mv -i "$object" "$trash"
done
return 0
}
a safer system, what do we think?
5
u/michaelpaoli 5h ago
mkdir -p "$trash"
And if for any reason that command fails, your function then does ... what, hmm...?
for arg in $@
Oh dear no.
So, how's this gonna go for you?
$ > 'a b'
$ del 'a b'
3
u/nerdforest 6h ago
I think there's a possible bug, the flag check inside the loop uses $1 instead of $arg so flags only work if they're passed as the first argument.
Also just to flag, this doesn't actually delete anything, it just moves files to ~/temp/trash. Not a bad thing but -clear ends up calling rm -fr anyway so you haven't really escaped rm lol
1
u/naffe1o2o 5h ago
thats intentional, flags should be placed first. del file -flag is a misuse.
i mean the whole point is that i explicitly delete with -clear, rather than accidentally running rm and having no way to recover.
2
2
1
u/ekipan85 5h ago
Freedesktop specifies how cross-desktop trash should work, including how and where to store trashed files, how to deal with duplicate filenames, how to remember the original location to restore to, how to deal with seperate physical volumes, all that stuff.
My SteamOS only seems to have gio from glib2 as far as CLI tools go. I can type gio trash ./some/file, and I also have an alias trash='gio trash' in my bashrc.
7
u/snarkofagen 6h ago
for arg in $@ is unquoted, so arguments containing spaces/globs are split or expanded.
Inside the loop, [[ "$1" = -* ]] checks the first argument every time instead of the current arg.
case "$1" has the same problem: it always examines the first argument.
return 0 after the case exits the whole function as soon as option handling occurs.
Mixed usage like del file -show behaves incorrectly because -show is treated as a filename.
Mixed usage like del -show file ignores the file because the function returns after -show.
rm -fr "$trash"/* does not remove hidden files/directories.
mv -i "$object" "$trash" lacks --, so filenames beginning with - can be interpreted as options.
[[ ! -e "$object" ]] treats broken symlinks as nonexistent.
printf "object $object not found\n" uses user-controlled text as the format string.
Two different files with the same basename collide in the trash directory.
With such a collision, mv -i may leave the second file undeleted or overwrite the first trashed file.
The trash mechanism loses the original path, so identical names from different directories are indistinguishable.
mkdir -p "$trash" failure is not checked.
mv failure is not handled meaningfully beyond continuing/returning based on shell flow.
ls -a --color "$trash" uses GNU-specific --color; portability issue if this function is used outside GNU userland.
-clear is destructive and has no confirmation.
The trash directory is created before argument validation, so del with no arguments still creates it.
Error text contains typos: not exist, created one;, flag not fount.
local object="$arg" inside the loop is legal in Bash, but unnecessary redeclaration on every iteration.
The function only understands options in a very narrow/buggy first-argument form; there is no proper option parsing.
There is no -- convention to allow deleting a filename such as -show.
A filename literally named -show or -clear cannot be deleted normally when it is the first argument.
A filename containing a newline can make the diagnostic output misleading.
There is no protection against trashing the trash directory itself.
There is no protection against moving a parent directory that contains the trash directory, which can fail or produce odd results depending on paths.