LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Please eyball my script (http://www.linuxquestions.org/questions/programming-9/please-eyball-my-script-727848/)

David the H. 05-22-2009 02:58 PM

Please eyball my script
 
The very first bash script I ever wrote was an attempt to create a "rmdir" program that protected me from accidentally deleting subfiles and directories. Well, what I created worked, but it's far from ideal.

So taking advantage of the experience I've gained over the last few years, I've spent the last few days writing a new version of it that's much smoother to use and adds a few new features, particularly protected directories.

I'd appreciate it if you all could look it over and kindly point out anything that needs fixing or could be improved. And feel free to use it or take advantage of it yourselves as well, of course. Thanks.

Code:

#!/bin/bash

## Ths script attempts to provide a safe and easy-to-use rmdir (remove
## directory) function. In addition to bash it requires rm, cat, find,
## grep, readlink, sort, and optionally tree.  All but grep and tree
## should be in the standard coreutilities package.


#### DOCUMENTATION ####
# (uses "here" documents to print everything
# between the "EndOfBlock" strings):

# This message will be printed if improper arguments are used.
USAGESIMPLE=$(cat <<EndOfBlock

        Usage:  $0 [-f|-h|-u] directory1 [directory2 ...]
              "$0 -h" for detailed help.

EndOfBlock)

# This message will be printed if the -h option is used.
USAGEFULL=$(cat <<EndOfBlock

 This script is designed to create a safer way to remove directories.
 It will first test for the existence of files or subdirectories inside the
 directory , and if any are found it will ask you what you want to do.


      Usage:  $0 [-f|-h|-u] directory1 [directory2 directory3 ...]

          -f  Force deletion of all listed directories
                (and their contents) without confirmation.
                Protected directories will be ignored.

          -h  Display this usage dialog.

          -u  Display a list of currently protected directories.


 Protected directories:

        You can designate a list of directories that will never be
        deleted by this script.  Simply add the directory names you
        want protected to one of the files "/etc/protecteddirs.txt"
        or "~/.protecteddirs.txt", with one directory path per line.
        (You can change the names and locations of the files by altering
        the variables "\$GLOBALFILE" and "\$USERFILE" in the script.)
        This script will read the contents of these two files, if they
        exist, each time it is run, and will refuse to delete any names
        listed in them.

        A directory path sent to the script may also match a substring
        of a protected path, so in addition to protecting the stated
        directory, it will also refuse to delete all parent directories
        as well.  e.g. if "/home/user/dir1/dir2" is protected, then
        attempting to delete "/home/user/dir1" will also fail.

        You can display a list of all currently protected directories
        with the "-u" option.

        Note that this feature is only a convenience function designed
        to prevent careless mistakes.  It will not completely protect
        your files from deletion and is not guaranteed to work in all
        cases.


 The file listing dialog ("tree" option):

        You will have the option to list all the files and subdirectories
        found inside the directory to be deleted (if any).  If your
        system has the "tree" application installed it will use it to
        display them in a nicely formatted directory tree.  Otherwise it
        will display a simple list of files using the find command.

EndOfBlock)


##### Script environment variable settings ####

ERROR_NOARGS=64                # No command arguments were given.
ERROR_USERCANCEL=66        # User canceled the operation.

IFS='
'                        # Set internal field separator to newline only
                        # to handle dirnames with spaces in them.

FORCED=0                # Initial setting for "force" option.

GLOBALFILE="/etc/protecteddirs.txt"  # Location of the global protected dirs file.
USERFILE="$HOME/.protecteddirs.txt"  # Location of the user protected dirs file.


#### Build a list of protected directories from the ####
#### "GLOBALFILE" and "USERFILE" files ####
#### if they exist. ####


PROTECTED=$(
for LINE in $(cat "$GLOBALFILE" "$USERFILE" 2>/dev/null|sort -u); do

  readlink -f "$LINE"

done
)

#### Test for existence of command options and arguments. ####
# Show usage message if nothing found, or if "-h" is found.
# Display all protected directories if "-u" is found.
# Set $FORCED variable to 1 if "-f" is found and shift the remaining
# arguments.

if [ -z $1 ]; then

        echo
        echo "No command arguments found."
        echo "You must supply at least one directory name."
        echo "$USAGESIMPLE"
        echo

        exit $ERROR_NOARGS

elif [ "$1" = "-h" ]; then

        echo "$USAGEFULL"
        echo

        exit 0

elif [ "$1" = "-u" ]; then

        echo "Directories protected from deletion:"
        echo
        echo -e "${PROTECTED:-No protected directories found.}"
        echo

        exit 0

elif [ "$1" = "-f" ]; then

        FORCED=1
        shift
        if [ -z $1 ]; then

          echo
          echo "No directories specified."
          echo "You must supply at least one directory name."
          echo "$USAGESIMPLE"
          echo

          exit $ERROR_NOARGS

        fi
fi


#### Main operation ####
#
# For each directory name fed to the command:
# 1: Check if it's a directory.  Skip it if not.
# 2: Check if it matches the protected list.  Skip it if it does.
# 3: If FORCED flag is on, delete the directory.
# else:
# 4a: If directory is empty, ask delete: yes/no/exit
# 4b: If directory is non-empty, ask delete: yes/no/show/exit
# Loop to next argument
#
#### ============== ####

echo "A Safer Remove Directory Script"
echo

for ENTRY in $@; do

ENTRYFULL="$(readlink -f "$ENTRY")"  # Get the absolute path for use in
                                    # file operations, while $ENTRY
                                    # will be used for most displays.

  echo -e "Processing: \"${ENTRYFULL:=$ENTRY}\"" # substitution necessary
                                                  # if dirname doesn't exist.

  if [ ! -d "$ENTRYFULL" ]; then

        echo "Not a directory.  Skipping."
        echo
        continue

  elif [[ "${PROTECTED:-null}" =~ $ENTRYFULL ]]; then

        echo "Matches a protected list entry.  Skipping."
        echo
        continue

  elif [ $FORCED = 1 ]; then

        if rm -rf "$ENTRYFULL" ; then
          echo "Directory deleted, including possible contents."
          echo -e "\(Forced deletion\)"
          echo
        else
          echo -e "Something went wrong.\nCheck output of rm for details"
          echo
        fi
        continue

  elif [[ $FORCED = 0 && $(find "$ENTRYFULL" -type d -prune -empty) ]];
then

        while true; do
          echo
          echo "Directory is empty.  Do you wish to delete it?"
          echo
          echo -e "\t[1|y] Delete  [2|n] Don't delete  [3|x] Exit script"
          echo -ne "\tSelect option: "
          read ANSWER

          case $ANSWER in
              "y"|"1")  if rm -rf "$ENTRYFULL" ; then
                          echo "Empty directory $ENTRY deleted."
                          echo
                          else
                                echo "Something went wrong."
                          echo "Check output of rm for details"
                          echo
                          fi
                        break
                        ;;

              "n"|"2")  echo "Directory $ENTRY not deleted."
                        break
                        ;;

              "x"|"3")  echo "Exiting script" ; exit $ERROR_USERCANCEL
                        ;;
                  * )  echo "Invalid choice.  Try again"
                        ;;
          esac
        done
        echo


  elif [[ $FORCED -eq 0 && ! $(find "$ENTRYFULL" -type d -prune -empty) ]];
then

        while true; do
          echo
          echo "WARNING!  Directory contains other files or folders!"
          echo "Do you wish to delete it?"
          echo
          echo -e "\t[1|y] Delete\t\t[2|n] Don't delete"
          echo -e "\t[3|s] Show files\t[4|x] Exit script"
          echo -ne "\tSelect option: "
          read ANSWER

          case $ANSWER in
              "y"|"1")  if rm -rf "$ENTRYFULL" ; then
                          echo "Directory $ENTRY and its contents deleted."
                          echo
                        else
                          echo "Something went wrong."
                          echo "Check output of rm for details"
                          echo
                        fi
                        break
                        ;;

              "n"|"2")  echo "Directory $ENTRY not deleted."
                        break
                        ;;
              "s"|"3")  echo "Displaying contents of $ENTRY:"
                        echo "======================="
                        echo
                        if [ -e /usr/bin/tree ]; then
                          tree -C --noreport "$ENTRYFULL"
                          echo
                        else
                          find "$ENTRYFULL" -printf "%p\n"
                          echo
                        fi
                        echo "======================="
                        ;;

              "x"|"4")  echo "Exiting script" ; exit $ERROR_USERCANCEL
                        ;;
                  * )  echo "Invalid choice.  Try again"
                        ;;
          esac
        done
        echo

  fi

done

exit 0

### TODO:  Add colors to output.



Edit: Updated version created. See below.

The_Kernel 05-22-2009 03:43 PM

So this isn't really the response you asked for, but isn't what you describe ("a... program that protected me from accidentally deleting subfiles and directories") exactly how rmdir works?

unSpawn 05-22-2009 03:46 PM

Quote:

Originally Posted by David the H. (Post 3549608)
The very first bash script I ever wrote was an attempt to create a "rmdir" program that protected me from accidentally deleting subfiles and directories. Well, what I created worked, but it's far from ideal.

Not to disrespect your script but why try to reinvent the wheel when there's already a solution that works (libtrash, see Freshmeat)?

David the H. 05-22-2009 04:04 PM

Well, when I first my first version way back when, I didn't even know that the gnu version of rmdir even existed. :) I just wanted a way to do it that was easier and safer than using 'rm -rf' all the time. But I've never really liked the official verison much in any case. It basically just refuses to do anything if the directory isn't empty, and that's it.

My script, OTOH, checks for the existence of subfiles, then asks you if you want to delete it all, cancel, or display a list of the files, so you can decide what you want to do from there. There's also a "force" option, so you can bypass the questioning if you want. And as I mentioned, I've also implemented a protected list, where you can specify directories that it will NEVER delete.

In short, it gives you a lot more control over the operation.

edit:

I took a look at libtrash once a while back too. But I don't want a trash can system either, just a simple extra layer of safety over the operation.

In any case, I wasn't asking for comments on why I wrote it, just to point out anything I can improve in what I did. :D

H_TeXMeX_H 05-22-2009 05:16 PM

I think you did a good job at doing what you wanted. I can't see anything wrong with the script.

For:

Code:

for LINE in $(cat "$GLOBALFILE" "$USERFILE" 2>/dev/null|sort -u); do
can't you just do:

Code:

for LINE in $(sort -u "$GLOBALFILE" "$USERFILE"); do

osor 05-23-2009 04:26 AM

It seems to me there are a lot of unnecessary indirection and unnecessarily large variables. For example, instead of creating a large string called USAGEFULL, which is to be echoed upon encounter of a help flag, just put it in a function, which you call.

Similarly, the construct
Code:

$(cat "$GLOBALFILE" "$USERFILE" 2>/dev/null|sort -u)
Or even (as suggested above)
Code:

for LINE in $(sort -u "$GLOBALFILE" "$USERFILE"); do
will create a temporary variable array-like object over which you will loop. It is unknown how big this can be, and possibly you might have funny side-effects (for example). If you pipe to a “while read” construct the data will be read as it is output from the sort command, and pipe buffering will take care of the potential problem (as an upside, you won’t have to change IFS, as read will only strip away leading whitespace).

So, stylistically (as well as for efficiency), you might want to change a lot of these sorts of constructs:
Code:

foo=$(bar)

# later on

echo $foo

into function calls (especially if the value is only used once).

Also, as you stated above, the script is not an equivalent of rmdir, but it does have some of the same functionality. You might want to isolate the portion that duplicates rmdir from that which is for protected files.

Also, be aware of portability (though this may not be as important in this situation). Using bash != having a GNU userspace. There are certain options which are available in GNU versions of utilities that aren’t available (or have different names) on other implementations (e.g., the printf flag on find). If you want to be safe, use no more than is specified in POSIX (though you can safely use “builtins” such as echo as long as you specify the bash shell).

David the H. 05-31-2009 12:36 PM

Sorry for not getting back for a few days. I had a busy week.

Thanks a lot for the suggestions. My main reason for asking was to improve my scripting ability. I'm trying to pay attention to efficiency and readability in what I write.

As for the comments:

The reason I didn't use...
Code:

for LINE in $(sort -u "$GLOBALFILE" "$USERFILE"); do
...or the like is that sort fails with an error message if either of the files is non-existent or unset. It refuses to output anything if it can't find all the files. The only easy way I found to get around it was to cat the text and pipe any errors away. If you know a better way to handle the errors, please let me know.

osor, that's a good point about the usage variables. I hadn't thought about how they are always created, even if not needed. My main intention with the "here" statements was to make the documentation easily readable within the script itself, as well as when executing. I'll try moving them into functions, though I'll probably keep them pretty much as-is otherwise.

I don't think I'll need to worry about overtaxing the for loop when reading the protected files though. I can't imagine them containing more than a few dozen lines in any reasonable usage scenario. But I may try out the while loop anyway just to see how it works. I generally prefer changing the IFS in any case though; it always seems to make things easier in the long run.

My biggest worry about the "protected" files is that I don't really like the idea of having to read them every time the program is run. I thought about using an environmental variable instead, but to my mind that's a bit harder to manage, as you'd have to mess with .bashrc and/or manipulate the string manually. It's much easier to edit a text file, so I went that way.

Quote:

You might want to isolate the portion that duplicates rmdir from that which is for protected files.
Not sure exactly what you mean here. I debated for a long time about exactly how to break up the process flow, but I finally decided that the simplest way to do it was to just run a single loop that checks all cases at once and does whatever's necessary. One loop handles everything.

Finally, no, I don't think portability is a big issue here. I did give it some consideration, but I doubt I'll ever need to run this on any system that doesn't have the basic gnu utilities. I did try to use external tools as little as possible though.

Of course if anyone else wants to use what I wrote they may have to take it into account. :)

bigearsbilly 06-03-2009 08:46 PM

over all nicely set out and readable.

maybe:

use getopt(s) to parse command line args.
use select rather than make your own menu.
error messsages to stderr

>&2 echo error
>&2 cat <<EOF (etc)

maybe more use of functions?

David the H. 06-05-2009 12:50 PM

Well, I've updated things a bit based on the suggestions I got. I moved the documentation into a function, and cleaned things up several places. I tried out some of the other things mentioned, but in the end decided that there wasn't that much need for major changes.

In particular I failed to find many places where functions would be really useful (other than the one above. To my mind functions are mostly for use when you need to do the same operation over and over, or conversely if the operation if only called under certain conditions and you don't want to load up the code with a lot of nested branches and stuff. But since most of what my script does is controlled through if-then branching anyway I see functions as being mostly superfluous. (Hmm...perhaps if I restructured the whole thing to be function oriented instead....)

I did change the part that tests for command line arguments from an if to a case statement. I don't know why I didn't do that in the first place, as I usually prefer using case statements for this kind of thing anyway. I think they're often cleaner and probably more efficient overall if there's only a single input to test for conditions.

Other than that I mostly just updated the output formatting. In particular I added color code escape sequences so that the output is more readable, and altered some of the wording.

@bigearsbilly: I tried using select at first, but I didn't like the looks of the output menus. Maybe it could be made to look better, but it's easier just to do it manually. I also decided getopts was unnecessary because the three flags I use are all independent of each other and should never need to be combined. Two of them are simple print-it-and-close options, and only the force flag requires additional inputs, all easily tested against. I may try it out in a future tweak though.

Here's my updated attempt:

Code:


#!/bin/bash

###########################################################################
##                                                                        ##
## Ths script attempts to provide a safe and easy-to-use rmdir (remove  ##
## directory) function. In addition to bash it requires rm, cat, find,  ##
## grep, readlink, sort, and optionally tree.  All but grep and tree    ##
## should be in the standard coreutilities package.                      ##
##                                                                        ##
###########################################################################

################### DOCUMENTATION ###########################
#############################################################

# (a function that uses "here" documents to print everything
# between the "EndOfBlock" strings):
# There are two levels, a simple usage message and a longer help document.
# The function must be called with an argument with a value of 1 or 2
# in order to determine which message gets printed.

##--------------begin documentation function---------------##
#############################################################
function print_documentation(){

if [ $1 -eq 1 ]; then

# This message will be printed if improper arguments are used.

USAGESIMPLE=$(cat <<EndOfBlock

        Usage:  $0 [-f|-h|-u] directory1 [directory2 ...]
              ${CYAN}"$0 -h" for detailed help.${UNSET}

EndOfBlock)

echo -e "${CYAN}You must supply at least one directory name.${UNSET}"
echo -e "$USAGESIMPLE"
echo

# This message will be printed if the -h option is used.

elif [ $1 -eq 2 ]; then

USAGEFULL=$(cat <<EndOfBlock

 ${CYAN}This script is designed to create a safer way to remove directories.
 It will first test for the existence of files or subdirectories inside the
 directory , and if any are found it will ask you what you want to do.$UNSET


      Usage:  $0 [-f|-h|-u] directory1 [directory2 directory3 ...]
          ${GREEN}
          -f  Force deletion of all listed directories
                (and their contents) without confirmation.
                Protected directories will be ignored.

          -h  Display this usage dialog.

          -u  Display a list of currently protected directories.


 ${CYAN}Protected directories:${UNSET}

        You can designate a list of directories that will never be
        deleted by this script.  Simply add the directory names you
        want protected to one of the files "/etc/protecteddirs.txt"
        or "~/.protecteddirs.txt", with one directory path per line.
        (You can change the names and locations of the files by altering
        the variables "\$GLOBALFILE" and "\$USERFILE" in the script.)
        This script will read the contents of these two files, if they
        exist, each time it is run, and will refuse to delete any names
        listed in them.

        A directory path sent to the script may also match a substring
        of a protected path, so in addition to protecting the stated
        directory, it will also refuse to delete all parent directories
        as well.  e.g. if "/home/user/dir1/dir2" is protected, then
        attempting to delete "/home/user/dir1" will also fail.

        You can display a list of all currently protected directories
        with the "-u" option.

        Note that this feature is only a convenience function designed
        to prevent careless mistakes.  It will not completely protect
        your files from deletion and is not guaranteed to work in all
        cases.


 ${CYAN}The file listing dialog ("tree" option):${UNSET}

        You will have the option to list all the files and subdirectories
        found inside the directory to be deleted (if any).  If your
        system has the "tree" application installed it will use it to
        display them in a nicely formatted directory tree.  Otherwise it
        will display a simple list of files using the find command.

EndOfBlock)

echo -e "$USAGEFULL"
echo
echo

fi

}

##--------------end documentation function----------------##
############################################################


##### Internal script environment variable settings ####
########################################################

GLOBALFILE="/etc/protecteddirs.txt"  # Location of the global protected dirs file.
USERFILE="$HOME/.protecteddirs.txt"  # Location of the user protected dirs file.

ERROR_NOARGS=64                # No command arguments were given.
ERROR_USERCANCEL=66        # User canceled the operation.

IFS='
'                        # Set internal field separator to newline only
                        # to handle dirnames with spaces in them.

FORCED=0                # Initial setting for "force" option.

#Define some color escape sequences for use in the output display.
RED='\e[0;31m'
WHITE='\e[1;37m'
BLUE='\e[1;34m'
GREEN='\e[0;32m'
CYAN='\e[0;36m'
UNSET='\e[0m'


#### Build a list of protected directories from the ########
#### "GLOBALFILE" and "USERFILE" textfiles if they exist.###
############################################################


PROTECTED=$(

for LINE in $(cat "$GLOBALFILE" "$USERFILE" 2>/dev/null|sort -u); do

  readlink -f "$LINE"

done
)



#### Test for existence of command options and arguments. ####
##############################################################

# Show usage message if nothing found, or if "-h" is found.
# Display all protected directories if "-u" is found.
# Set $FORCED variable to 1 if "-f" is found and shift the remaining
# arguments.

case $1 in

        #If no arguments given:
  "")        echo -e ${RED}
        echo -e "No command arguments given.${UNSET}"
        print_documentation 1  # Call documentation function with arg "1".
        exit $ERROR_NOARGS
  ;;

        #'-h' Print full documentation
  -h)        print_documentation 2  # Call documentation function with arg "2".
        exit 0
  ;;

        #'-u' List protected directories
  -u)        echo
        echo -e "${CYAN}Directories protected from deletion:${UNSET}"
        echo
        echo -e "${PROTECTED:-No protected directories found.}"
        echo

        exit 0
  ;;

        #'-f' Set forced flag
  -f)        FORCED=1
        shift
        if [ -z $1 ]; then  #check for existence of a second argument.

          echo -e ${RED}
          echo -e "No directories specified.${UNSET}"
          print_documentation 1
          exit $ERROR_NOARGS

        fi

esac

####--------------- Main operation loop------------------ ####
##############################################################
#
# For each directory name fed to the command:
#
# 1: Check if it's a directory.  Skip it if not.
# 2: Check if it matches the protected list.  Skip it if it does.
# 3: If FORCED flag is on, delete the directory.
# else:
# 4a: If directory is empty, ask delete: yes/no/exit
# 4b: If directory is non-empty, ask delete: yes/no/show/exit
# Loop to next argument
#
###############################################################


# Display welcome line.
echo
echo -e "${WHITE}A Safer Remove Directory Script"
echo -e "-------------------------------${UNSET}"
echo

# Start the main loop

for ENTRY in $@; do

ENTRYFULL="$(readlink -f "$ENTRY")"  # Get the absolute path for use in
                                    # file operations, while $ENTRY
                                    # will be used for most displays.


# Display the filename being currently worked on.

echo -e "Processing: ${BLUE}\"${ENTRYFULL:=$ENTRY}\"${UNSET}"

# The substitution is necessary if dirname doesn't exist.


# Function for testing if directory has contents.  To be used later.  #
##-------------------------------------------------------------------##

function empty_test() {

        test $(find ${ENTRYFULL:-$ENTRY} -type d -prune -empty)
        echo $?

}

## End function ---------------------------------------------------##


#########################
### Start the checks ####
#########################

# Check if entry is a directory or not:


  if [ ! -d "$ENTRYFULL" ]; then

        echo -e "  \"$ENTRY\" is not a directory (or doesn't exist)."
        echo -e "    ${CYAN}Skipping.${UNSET}"
        echo
        continue

# Check if entry is protected or not:

  elif [[ "${PROTECTED:-null}" =~ $ENTRYFULL ]]; then

        echo -e "  \"$ENTRY\" matches a protected list entry."
        echo -e "    ${CYAN}Skipping.${UNSET}"
        echo
        continue

# Delete without question if forced flag is set:

  elif [ $FORCED = 1 ]; then

        if rm -rf "$ENTRYFULL" ; then
          echo "  \"$ENTRY\"" Deleted.
          echo -e "    ${CYAN}Forced deletion of directory and any contents.${UNSET}"
          echo
        else
          echo -e "${RED}Something went wrong.\nCheck output of rm for details${UNSET}"
          echo
        fi
        continue

# Otherwise check if empty or not:

# If empty:

  elif [[ $FORCED -eq 0 && $(empty_test) -eq 0 ]]; then

        while true; do
          echo -e "  ${CYAN}Directory is empty.  Do you wish to delete it?"
          echo
          echo -e "${GREEN}\t[1|y] Delete  [2|n] Don't delete  [3|x] Exit script"
          echo -ne "${BLUE}\tSelect option: ${UNSET}"
          read ANSWER

          case $ANSWER in
              "y"|"1")  if rm -rf "$ENTRYFULL" ; then
                          echo
                          echo -e "  Empty directory \"$ENTRY\" deleted."
                          echo
                          else
                          echo
                                echo -e "${RED}Something went wrong."
                          echo -e "Check output of rm for details${UNSET}"
                          echo
                          fi
                        break
                        ;;

              "n"|"2")  echo
                        echo -e "  Directory \"$ENTRY\" left untouched."
                        echo -e "    ${CYAN}Delete action canceled by user.${UNSET}"
                        break
                        ;;

              "x"|"3")  echo
                        echo -e "${RED}Exiting script.${UNSET}"
                        exit $ERROR_USERCANCEL
                        ;;

                  * )  echo
                        echo -e "${RED}Invalid choice.  Try again.${UNSET}"
                        ;;
          esac
        done
        echo


  elif [[ $FORCED -eq 0 && $(empty_test) -ne 0 ]]; then

        while true; do
          echo
          echo -e "${RED}##### WARNING! ${CYAN}Directory \"$ENTRY\" contains other files or folders! ${RED}#####"
          echo -e "  ${CYAN}Do you wish to delete it?${UNSET}"
          echo
          echo -e "\t${GREEN}[1|y] Delete\t\t[2|n] Don't delete"
          echo -e "\t[3|s] Show files\t[4|x] Exit script"
          echo -ne "\t${BLUE}Select option: ${UNSET}"
          read ANSWER

          case $ANSWER in
              "y"|"1")  if rm -rf "$ENTRYFULL" ; then
                          echo
                          echo -e "  ${CYAN}Directory \"$ENTRY\" and its contents deleted.${UNSET}"
                          echo
                        else
                          echo
                          echo -e "${RED}Something went wrong."
                          echo - "Check output of rm for details${UNSET}"
                          echo
                        fi
                        break
                        ;;

              "n"|"2")  echo
                        echo -e "  Directory \"$ENTRY\" left untouched."
                        echo -e "    ${CYAN}Delete action canceled by user.${UNSET}"
                        break
                        ;;

              "s"|"3")

                        #small function for printing variable-length underline strings.
                        #prints $1 number of spaces, then subsitutes them with equal signs.

                        function varline() {
                                        printf -v line "%$1s" ""
                                        printf "%s" "${line// /=}"
                                          }

                        echo
                        echo -e "  Displaying contents of \"$ENTRY\":"
                        echo -e "  ==========================$(varline ${#ENTRY})"
                        echo
                        if [ -e /usr/bin/tree ]; then
                          tree -C --noreport "$ENTRYFULL"
                          echo
                        else
                          find "$ENTRYFULL" -printf "%p\n"
                          echo
                        fi

                        echo -e "  ==========================$(varline ${#ENTRY})"

                        ;;

              "x"|"4")  echo
                        echo -e "${RED}Exiting script${UNSET}"
                        exit $ERROR_USERCANCEL
                        ;;

                  * )  echo
                        echo -e "${RED}Invalid choice.  Try again.${UNSET}"
                        ;;
          esac
        done
        echo

  fi

done

echo -e "${BLUE}All entries processed.  Goodbye!${UNSET}"

exit 0



All times are GMT -5. The time now is 09:25 PM.