Skip to content

Instantly share code, notes, and snippets.

@zkytony
Created October 21, 2017 15:49
Show Gist options
  • Save zkytony/7f4580930f6bbaaad48b22441c2e983f to your computer and use it in GitHub Desktop.
Save zkytony/7f4580930f6bbaaad48b22441c2e983f to your computer and use it in GitHub Desktop.
Safe rm - moves deleted files to a dumping ground
# Some important aliases
SAFE_RM_DIR=${SAFE_RM_DIR:="$HOME/.safe_rm"}
REAL_RM=${REAL_RM:="/bin/rm"}
# Override rm, because it's always painful to recover
# files deleted by rm, if possible at all. Instead,
# simply move it to the $SAFE_RM_DIR for later cleaning.
rm()
{
force=false
recursive=false
other=false
help=false
# Process arguments.
len=0
for arg in "$@"
do
if [[ "$arg" == -* ]]; then
# Obtain the options portion of this arg. Compare
# with all possible options for the rm command. This
# means files with the same name as these options with
# a dash character at the front won't be successfully removed.
opt=${arg:1}
if [[ "$opt" =~ ^(f|-force)$ ]]; then
# If it's tryping to force remove, set the force flag.
force=true
elif [[ "$opt" =~ ^(r|R|-recursive)$ ]]; then
# If it's trying to recursively remove, set the recursive flag
recursive=true
elif [[ "$opt" =~ ^(i|I|-interactive|-one-file-system|-no-preserve-root|-preserve-root|d|-dir|v|-verbose|-version)$ ]]; then
other=true
elif [[ "$opt" =~ ^(h|-help)$ ]]; then
help=true
else
# Not recognized as rm option. Exit.
echo -e "${LRED}Error: Unrecognized option '${arg}'${NC}"
return 1
fi
else
# Normal file
files[$len]="${arg}"
((len++))
fi
done
# If help is set, ignore all other arguments and print help message.
if [ "$help" = true ]; then
echo -e "${BOLD}rm: Safe rm command.${NORMAL}"
echo -e " Instead of calling ${REAL_RM}, will instead move the deleted files to ${SAFE_RM_DIR}."
echo -e " If ${SAFE_RM_DIR} does not exist, it will be created. ${BOLD}Use '-r' to remove directories.${NORMAL}\n"
echo -e " The original 'rm' is at ${REAL_RM}.\n"
return 0
fi
# If force is set, exit.
if [ "$force" = true ]; then
echo -e "${LRED}Error: Custom rm! ${LGRAY}Use '${REAL_RM} -f' to force delete files.${NC}"
return 1
fi
# If other options, exit, print warning
if [ "$other" = true ]; then
echo -e "${LRED}Error Custom rm! ${LGRAY}Try '${REAL_RM} $@' instead?${NC}"
return 1
fi
# Check if ${SAFE_RM_DIR} exists. If not, create one.
mkdir -p "${SAFE_RM_DIR}"
for ((j=0;j<len;j++))
do
# (For self-awareness): Check if any of the file is a directory. If so, recursive flag must be on.
if [[ -d "${files[$j]}" ]] && [ "$recursive" = false ]; then
echo -e "${LRED}Error: ${files[$j]} is a directory. ${LGRAY}Nothing is removed.${NC}"
return 1
fi
done
for ((j=0;j<len;j++))
do
mv "${files[$j]}" "${SAFE_RM_DIR}"
done
return 0
}
# Yet, if someone really wants to remove, he should use
# the new alias for `rm` command. Still, enforce interative
# by default. One can definitely use 'yes' command to skip it.
alias rrm='${REAL_RM} -I -v'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment