#!/bin/sh # trm.sh - Safer 'rm' And Backup Utility # Copyright (c) 2016 TundraWare Inc., Des Plaines, IL USA # All Rights Reserved # Permission granted for the free use of this program without restriction COPYRIGHT='2016' GITID='1ca95bc tundra Fri Oct 28 09:27:57 2016 -0500' VERSION='1.102' OLDIFS=${IFS} # Preserve IFS for later use in protecting files/dirs with spaces in their name GRAVEYARD="${HOME}/.graveyard" INTERPROMPT="Do You Want To Remove(Copy):" TESTING="Test Mode ..." mkdir -p $GRAVEYARD ##### # Display usage information ##### trm_usage() { echo "trm.sh ${VERSION} - Copyright (c) ${COPYRIGHT} , TundraWare Inc. All Rights Reserved." echo "http://www.tundraware.com/Software/trm" echo "" echo "Usage: trm.sh [-Vcdhistvx] [-g graveyard] file|dir [...]" echo " where," echo " -V display version control commit ID" echo " -c copy targets to graveyard, don't remove them" echo " -d empty the current graveyard (permanent removal)" echo " -h display this help screen" echo " -g graveyard use named graveyard instead of default" echo " -i interactive removal/copy" echo " -s don't generate serial number suffixes" echo " -t test mode, just show what would be done" echo " -v verbose mode - be noisy" echo " -x execute, overrides previous -t" } ##### # This function is called at the bottom of this file or it can # be embedded in a shell startup script. ##### # Pick up the environment variable settings if any, and go trm() { trm_go $TRM "$@" } trm_go() { # Parse command line args OPTLIST='Vcdg:histvx' # List of all legal command line options OPTIND=1 # in case getopts was previously used in this context # Defaults INTERACTIVE="" OPERATOR="mv" # Can be overriden with -c option SERIALNO="Yes" # Generate serial numbers TESTMODE="" VERBOSE="" while getopts ${OPTLIST} opt do case $opt in # Print git commit ID V) echo ${GITID} ;; # Copy, don't move, targets to graveyard c) OPERATOR="cp -pr" ;; # Empty the graveyard d) if [ -z "${TESTMODE}" ] then rm -rf ${VERBOSE} ${GRAVEYARD}/* ${GRAVEYARD}/.[-z]* fi ;; # Name your own graveyard g) GRAVEYARD=${OPTARG} ;; h) trm_usage return 0 ;; i) INTERACTIVE="Yes" ;; # Turn of serial number generation s) SERIALNO="" ;; # Don't do anything, just show what you would do t) TESTMODE=${TESTING} ;; # Be noisy v) VERBOSE="-v" ;; # Actually execute x) TESTMODE="" ;; *) trm_usage return 1 ;; esac done # Process rest of command line arguments shift $((OPTIND-1)) # Notify if in test mode if [ -n "${TESTMODE}" ] && [ $# -gt 0 ] then echo ${TESTMODE} fi while [ $# -gt 0 ] do # Symlinks require special care if [ -L "$1" ] then # Bare symlink itelf REALPATH=$(readlink -f -- $(dirname -- "$1")) if [ "${REALPATH}" = '/' ] then REALPATH="" fi REALPATH="${REALPATH}"/$(basename -- "$1") # Process normal files and directories else REALPATH=$(readlink -f -- "$1") fi # See if we want serial numbers SERIAL="" if [ -n "${SERIALNO}" ] then SERIAL=".$(date +%Y%m%d%H%M%S)" fi # Figure out absolute paths for source and destination SRCDIR=$(dirname -- "${REALPATH}") if [ "${SRCDIR}" = '/' ] then SRCDIR="" fi SRCFIL=$(basename -- "${REALPATH}") DESDIR="${GRAVEYARD}${SRCDIR}" DESFIL="${SRCFIL}${SERIAL}" # Temporarily assign field separator to a character never used in # a filename. Needed to preserve spaces in file/dirnames IFS='>' CMD="${OPERATOR} $VERBOSE -- '${REALPATH}' '${DESDIR}/${DESFIL}'" # If we're in test mode, just show what we would do if [ -n "${TESTMODE}" ] then echo ${CMD} # We're really doing this else # Handle interactive requests if [ -n "${INTERACTIVE}" ] then echo -n "${INTERPROMPT} ${REALPATH}? " read doit if [ "${doit}" != "y" ] && [ "${doit}" != "Y" ] then shift continue fi fi # Make sure the destination directory exists and do the work mkdir -p "${DESDIR}" eval ${CMD} fi shift IFS=${OLDIFS} done } ##### # Run now if invoked directly on the command line. (Otherwise, we're # just loading the function above into the current shell context.) ##### # Login shells report $0 with a leading "-". This breaks 'basename', # so we have to tell it not to treat the dash as an option delimiter. if [ $(basename -- "$0") = "trm.sh" ] then trm "$@" fi