#!/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='48405b2 tundra Thu Oct 27 20:36:38 2016 -0500' VERSION='1.101' 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 -cehinstvx -g graveyard [file|dir] ..." echo " where," echo " -c copy targets to graveyard, don't remove them" echo " -e 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 " -n noisy output - verbose mode" echo " -s don't generate serial number suffixes" echo " -t test mode, just show what would be done" echo " -v display version control commit ID" 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='ceg:hinstvx' # 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 # Copy, don't move, targets to graveyard c) OPERATOR="cp -pr" ;; # Empty the graveyard e) 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" ;; # Be noisy n) VERBOSE="-v" ;; # Turn of serial number generation s) SERIALNO="" ;; # Don't do anything, just show what you would do t) TESTMODE=${TESTING} ;; # Print git commit ID v) echo ${GITID} ;; # 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}" 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 done } ##### # Run now if invoked directly on the command line. (Otherwise, we're # just loading the function above into the current shell context.) ##### # For some reason, bash on FreeBSD returns $0 with a leading "-" # which breaks the logic if we don't scrub it out here. if [ $(basename $(echo "$0" | sed s/^-//)) = "trm.sh" ] then trm "$@" fi