LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-22-2009, 01:58 PM   #1
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
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.

Last edited by David the H.; 06-05-2009 at 11:52 AM.
 
Old 05-22-2009, 02:43 PM   #2
The_Kernel
LQ Newbie
 
Registered: Nov 2008
Posts: 19

Rep: Reputation: 0
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?
 
Old 05-22-2009, 02:46 PM   #3
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Quote:
Originally Posted by David the H. View Post
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)?
 
Old 05-22-2009, 03:04 PM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Original Poster
Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
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.

Last edited by David the H.; 05-22-2009 at 03:12 PM.
 
Old 05-22-2009, 04:16 PM   #5
H_TeXMeX_H
LQ Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301
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
 
Old 05-23-2009, 03:26 AM   #6
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
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).
 
Old 05-31-2009, 11:36 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Original Poster
Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
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.

Last edited by David the H.; 05-31-2009 at 11:38 AM.
 
Old 06-03-2009, 07:46 PM   #8
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
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?
 
Old 06-05-2009, 11:50 AM   #9
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Original Poster
Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
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
 
  


Reply

Tags
bash, rmdir, script



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Need help with script to organise files into folders as part of DVD backup script jasybee2000 Linux - Newbie 5 06-15-2009 07:29 PM
MySQL Updates With Null When Perl Script Run From Shell Script ThisGuyIKnow Programming 6 08-12-2008 09:56 AM
Iptables (with masq) troubleshooting, very simple script attached script and logs. xinu Linux - Networking 13 11-01-2007 04:19 AM
i get an error message running php script inside a cgi script. repolona Linux - Software 0 02-22-2007 09:10 PM
send automatic input to a script called by another script in bash programming jorgecab Programming 2 04-01-2004 12:20 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:48 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration