================================== FREEBIES & MHO ON SCRIPTING STYLE Commented Code Samples A through J - Dan Martin - ================================== ALERT: The code segments offered below have been "beautified" with a left indent. Special care must therefore be taken when using "Copy and Paste" to embed my code into yours. You MUST make sure the left indent is removed, like this: ---- BEFORE: ---- cat << BOX | tee -a $log_fi #### NORMAL TERMINATION #### SCRIPT ENDED: `which $1` AS OF: `date` LOG FILE: $log_fi BOX ---- AFTER: ---- cat << BOX | tee -a $log_fi #### NORMAL TERMINATION #### SCRIPT ENDED: `which $1` AS OF: `date` LOG FILE: $log_fi BOX A) # All scripts should take care of logging their own activities. # Below is an example of establishing a time-stamped log-file # name and also of placing appropriate header info within it: # bsnm=`basename $0` # Acquires root name of script if no extension bsnm=`basename $0 .ksh` # .ksh extension is removed from filename [[ -d "${HOME}/log" ]] && LOGDIR="${HOME}/log" || LOGDIR="/tmp" log_fi=${LOGDIR}/${bsnm}_D`date +%Y%m%d"_T"%H%M%S`.log # log file path name # $0 always contains the name of the currently running script touch $log_fi chmod 666 $log_fi # Example new log filename: /u/dxmar33/log/var_test_D20010424_T092837.log # cat <>$log_fi SCRIPT RUNNING IS: `which $0` BEGIN RUN AS OF: `date` LAUNCHED BY USER: $LOGNAME (real: `logname`) FROM SERVER: `uname -n` LOG FILE: $log_fi WORKING DIRECTORY: `pwd` BOX # Note that "BOX" above >must< appear at hard-left margin of line B) # Provide a switch to turn on or off various debug comments # which are appended to both screen & log as in this example: yak="Y" # If "Y" then log comments [[ "$yak" = "Y" ]] && echo "This is a blabbery..." | tee -a $log_fi C) # A combination logging/exit function should be established # which can be called from any point in the script as needed: function _dang { # Required Arguments: $1 = Name of this Program # $2 = Exit Error-Code (non-zero) # $3 = User-Abuse string cat << BOX | tee -a $log_fi #### ABNORMAL TERMINATION ALERT #### SCRIPT ABENDED: `which $1` AS OF: `date` LOG FILE: $log_fi EXIT CODE: $2 REASON: $3 BOX exit $2 } # EOF _dang D) # Arguments should be counted and logged* as in this example: [[ "$#" < 1 ]] && _dang "$0" 5 "No Arguments were given!" loop=1 while [[ "$loop" -le "$#" ]] do echo "\tArg # $loop = \"`eval print '$'$loop`\"" >>$log_fi loop=`expr $loop + 1` # ksh 88 # ((loop = loop + 1)) # ksh 93 done echo >>$log_fi # * Not a good idea if any arguments would be passwords! E) # Population of critical variables should always be verified # before the script is allowed to continue as in this example # which appends exceptions to both the log file and the screen: all='well' for rav in PAGER EDITOR HOME TONTO LOGNAME SHELL ZAPIT \ ORACLE_HOME SHEDIT TERM do if [[ -z "`eval print '$'$rav`" ]] then all="sick" echo "\n**** ALERT: \"$rav\"\tis NOT SET! ****\n" \ | tee -a $log_fi else echo "Variable \"$rav\" \tIS set to \"`eval print '$'$rav`\"" >>$log_fi fi done # Note use of _dang function to log abend and stop script: [[ "$all" = "sick" ]] && _dang "$0" 57 "FATAL VARIABLE-POPULATION ERROR(s)" F) # Create a function to solicit Y/N answers from the User: function _ask { # Required Arguments: $1 = Question-string # Populates $ans with either Y or N ans='' while [[ -z "$ans" ]] do echo "\n$1 (Y/N): \c" read ans done case "$ans" in y|Y) ans="Y" ;; *) ans="N" ;; esac } # EOF _ask() # Sample usage: _ask "So far, so good. Continue Running? (Y/N)" [[ "$ans" = "Y" ]] && echo "Continue-Run affirmed" | tee -a $log_fi \ || _dang "$0" 94 "User elected to Stop-Run" G) # Trap and log User-termination: trap "_dang \"$0\" 9 \"Terminated by User\"." 2 H) # Make sure all critical files (including any that # are dotted-in) actually exist as in this example: for ck in "$HOME/duh.properties" /tmp/drm /usr/bin/ksh do [[ -f "$ck" ]] && echo "File \"$ck\" found OK" >>$log_fi \ || _dang "$0" 91 "File \"$ck\" NOT FOUND!" done # Use [[ -x "$ck" ]] to check for executability I) # Be sure to define and comment variables so that they # can easily be used as convient run-time switches: # export duhba="ON" # If "ON", all procs will be made to run as DBA # export duhba="OFF" # export infmx="ON" # If "ON", all procs will be made owned by "informix". export infmx="OFF" J) # Log normal termination and exit status. # Also end the script visually, as in: cat << BOX | tee -a $log_fi #### NORMAL TERMINATION #### SCRIPT ENDED: `which $1` AS OF: `date` LOG FILE: $log_fi BOX exit 0 # EOF