shell: add rm-prefer-trash script
This commit is contained in:
parent
58b3d6122e
commit
51616211d8
1 changed files with 170 additions and 0 deletions
170
.config/shell/bin/rm-prefer-trash
Executable file
170
.config/shell/bin/rm-prefer-trash
Executable file
|
@ -0,0 +1,170 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# cause plain rm wasn't good enough
|
||||||
|
# auto selects what trash directory to put files in if rmtrash is available
|
||||||
|
# otherwise, uses rm
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
rm='rm'
|
||||||
|
|
||||||
|
err_differing_filesystems() {
|
||||||
|
echo 'Error: some files are apart of different filesystems.' >&2
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
echo 'Either set RM=rm to force not using `trash`, or remove the files individually' >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
fs(){
|
||||||
|
df "$1" | sed '1d' | cut -d ' ' -f 1
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg() {
|
||||||
|
echo "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
rm_warning() {
|
||||||
|
echo 'WARNING: using rm - NOT trash. Files will be PERMINANTLY DELETED!' >&2
|
||||||
|
printf '%s' "Type Y to continue: " >&2
|
||||||
|
read -r confirm
|
||||||
|
if [ "$confirm" != 'Y' ]; then
|
||||||
|
printf '\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo 'Waiting 3 seconds before continuing.' >&2
|
||||||
|
sleep 3
|
||||||
|
}
|
||||||
|
|
||||||
|
rm_custom_warning() {
|
||||||
|
echo 'WARNING: using custom rm command: '"$rm" >&2
|
||||||
|
echo 'This might NOT use the trash'
|
||||||
|
echo ''
|
||||||
|
echo 'Waiting 5 seconds before continuing.' >&2
|
||||||
|
sleep 5
|
||||||
|
}
|
||||||
|
|
||||||
|
err_no_trashdirs() {
|
||||||
|
echo 'Error: No trash directorys with matching filesystems are available.' >&2
|
||||||
|
echo 'Please set TRASH_DIRS to a colon-separated list of your preferred trash directories.' >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Wrapper for rm and rm-trash commands"
|
||||||
|
echo ""
|
||||||
|
echo "Environment:"
|
||||||
|
echo " RM Force using a particular rm command."
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
echo ' TRASH_DIRS What directories to use as trash locations for `trash`.'
|
||||||
|
echo ' DRY Dry run: print the rm command instead of executing it.'
|
||||||
|
echo ""
|
||||||
|
echo "Usage:"
|
||||||
|
echo " ${0##*/} [ARGS]"
|
||||||
|
echo ""
|
||||||
|
echo "Where ARGS is the argument list corresponding to the rm command to be used."
|
||||||
|
echo ""
|
||||||
|
echo "Current selection for rm command: $which_rm"
|
||||||
|
}
|
||||||
|
|
||||||
|
do_rm() {
|
||||||
|
if [ "${DRY:-false}" = true ]; then
|
||||||
|
echo "$rm" "$@"
|
||||||
|
else
|
||||||
|
"$rm" "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
do_rmnormal() {
|
||||||
|
# shellcheck disable=SC2209
|
||||||
|
rm=rm
|
||||||
|
rm_warning
|
||||||
|
do_rm "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
do_rmcustom() {
|
||||||
|
# check if we have been given an rm command
|
||||||
|
rm="$RM"
|
||||||
|
rm_custom_warning
|
||||||
|
do_rm "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
do_rmtrash() {
|
||||||
|
# get trash directories
|
||||||
|
trash_default_fallback="$HOME"/.local/share
|
||||||
|
trash_default="${XDG_DATA_HOME:-"$trash_default_fallback"}/Trash"
|
||||||
|
trashdirs="${TRASH_DIRS:-"$trash_default"}"
|
||||||
|
|
||||||
|
# if trash is available, use it
|
||||||
|
rm='trash'
|
||||||
|
fs1=''
|
||||||
|
# validate that all files are on the same filesystem
|
||||||
|
for a; do
|
||||||
|
if [ -e "$a" ]; then
|
||||||
|
fs="$(fs "$a")"
|
||||||
|
if [ -z "$fs1" ]; then
|
||||||
|
fs1="$fs"
|
||||||
|
# this will only run the first time through the loop
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# ensure all files are on the same filesystem
|
||||||
|
if [ "$fs1" != "$fs" ]; then
|
||||||
|
err_differing_filesystems
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$fs1" != '' ]; then
|
||||||
|
# if we get here, we have validated that all the files are on the same filesystem
|
||||||
|
trashdir=''
|
||||||
|
found_trash=false
|
||||||
|
while [ "$trashdirs" != "$trashdir" ]; do
|
||||||
|
trashdir="${trashdirs%%:*}"
|
||||||
|
trashdirs="${trashdirs#"$trashdir":}"
|
||||||
|
fs="$(fs "$trashdir")"
|
||||||
|
if [ "$fs" = "$fs1" ]; then
|
||||||
|
found_trash=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$found_trash" = true ]; then
|
||||||
|
set -- --trash-dir "$trashdir" "$@"
|
||||||
|
else
|
||||||
|
err_no_trashdirs
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "trash dir:" "$trashdir"
|
||||||
|
do_rm "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
# which rm command to use
|
||||||
|
rm=''
|
||||||
|
|
||||||
|
# calculate which rm command to use
|
||||||
|
which_rm=''
|
||||||
|
if [ -n "${RM:-}" ]; then
|
||||||
|
which_rm='custom: '"$RM"
|
||||||
|
elif command -v trash > /dev/null; then
|
||||||
|
which_rm='trash'
|
||||||
|
else
|
||||||
|
which_rm='rm'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# print usage information (including which rm command we'll use)
|
||||||
|
if [ $# = 0 ]; then
|
||||||
|
usage
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# execute rm
|
||||||
|
case "$which_rm" in
|
||||||
|
rm)
|
||||||
|
do_rmnormal "$@";;
|
||||||
|
trash)
|
||||||
|
do_rmtrash "$@";;
|
||||||
|
custom*)
|
||||||
|
do_rmcustom "$@";;
|
||||||
|
*)
|
||||||
|
usage; exit;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
Loading…
Add table
Reference in a new issue