Newer
Older
trm / trm.sh
#!/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='7ba2a78 tundra Tue Dec 6 18:22:17 2016 -0600'
VERSION='1.104'
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