# SccsId[] = "%W% (USL function) %G%"
EAR_name="EXIT_IF_ALREADY_RUNNING"
if [ ".${SECONDS}" = "." ]; then # Bourne function already loaded?
[ ."`set|egrep '^$EAR_name\(\)\{$'`" != . ] && EAR_loaded=1
else # Korn or Bash shell and function already loaded?
if [ `expr "\`uname -s\`" : "[Ll][Ii][Nn][Uu][Xx]"` -eq 0 ]; then
[ ."`typeset +f|awk '/^'$EAR_name'[=\(]?/'`" != . ] && EAR_loaded=1
else # Linux
[ ."`typeset -F|awk '/^'$EAR_name'[=\(]?/'`" != . ] && EAR_loaded=1
fi
fi
if [ 0${EAR_loaded} -eq 0 ]; then
#----------------------------------------------------------------------#
EXIT_IF_ALREADY_RUNNING() # Function documentation located at bottom. #
#----------------------------------------------------------------------#
{ [ ."${AWK}" = . ] && { { [ -x /usr/bin/nawk ] && AWK=/usr/bin/nawk; } \
|| { [ -x /bin/gawk ] && AWK=/bin/gawk ; } \
|| { [ -x /usr/bin/awk ] && AWK=/usr/bin/awk ; }; }
if [ .${SHLIB} = . ]; then SHLIB=/usr/local/scripts; export SHLIB; fi
. $SHLIB/email_msg.sh # Calls $SHLIB/exit.sh
. $SHLIB/write_err_to_syslogs.sh
#------------------------------------------------------------#
# If the following variables are not set, use these defaults.#
#------------------------------------------------------------#
: ${id_num=`id|sed 's/^\(uid=\)\([0-9]*\)\(.*\)/\2/'`}
: ${id_hex=`echo "obase=16;$id_num"|bc`}
: ${script_name:=`basename $0`}
: ${name_root:=`echo $script_name|$AWK '{sub(/^\.+/,"");sub(/\..*/,"");print}'`}
: ${yymmddhhmiss:=`date '+%y''%m%d%H''%M''%S'`}
: ${Xtimestamp:=`echo "obase=16;$yymmddhhmiss+$$"|bc`}
: ${sp:=" "}
: ${tmp:=/var/tmp}
: ${OZ:=`uname -s 2> /dev/null|tr '[A-Z]' '[a-z]' 2> /dev/null`}
if [ ."$ps_opts" = . ]; then
if [ ."$OZ" != ."linux" ]; then
EAR_ps_opts="-f -u $id_num"
else
EAR_ps_opts='-aux'
fi
fi
if [ ."$log" = . ]; then
log=$name_root.log
[ ."$teelog" = . ] && teelog="cat"
fi
EAR_ID="$script_name($EAR_name)"
#----------------------------#
# Parse any function options.#
#----------------------------#
EAR_option=0
EAR_opt_l=0
EAR_opt_p=0
EAR_opt_t=0
EAR_pri="$logger_p" # $logger_p and $logger_t are assigned defaults
EAR_tag="$logger_t" # within library defaults.sh.
EAR_root=$tmp/$name_root"_EAR_go_"$id_hex
EAR_err=$EAR_root"."$Xtimestamp
while getopts lp:t: EAR_opt 2>> $EAR_err
do
#-----------------------------------------------------------------#
# The EAR_option and EAR_opt_l are necessary to prevent possible #
# command options (which must be specified after function #
# options) from being confused with function options. #
#-----------------------------------------------------------------#
case $EAR_opt in
l ) EAR_opt_l=1
EAR_option=1
;;
p ) EAR_opt_p=1
EAR_pri="$OPTARG"
EAR_option=1
;;
t ) EAR_opt_t=1
EAR_tag="$OPTARG"
EAR_option=1
;;
\? ) echo "$EAR_ID" \
"Invalid option: -`sed 's/^.*-- //' $EAR_err`" 1>&2
;;
* ) ;;
esac
done
[ $EAR_option -ne 0 ] && shift `expr $OPTIND - 1` # Shift past options to remaining args
[ ."$EAR_root" != . ] && \rm -f $EAR_root* > /dev/null 2>&1
#----------------------------------------------------------------#
# Must reset this dog if this function is apt to be called again #
OPTIND=1 # (try and find this fact documented anywhere else). #
#----------------------------------------------------------------#
#----------------------------------------------------------------#
# Awk script assumes variables 'sp' and 'pid' are passed to it. #
#----------------------------------------------------------------#
EAR_awk_scr='BEGIN {n=0}
$2 == pid {
gsub(/[\t ]+/, " ", $0)
sub(/^[\t ]*/, sp, $0)
print
n++
}
END {exit n}'
#----------------------------------------------------------------#
EAR_CREATE_FILE() # Subfunction to create $active_status_file. #
#----------------------------------------------------------------#
{ #
echo "`date '+%Y-%m-%d %T'`" \
"echo $$ > $active_status_file" | $teelog
echo $$ > $active_status_file
if [ $? -eq 0 ]; then
chmod 0644 $active_status_file
return 0 # Ah, the sweet smell of success.
else
EAR_m1="Problem creating $active_status_file!"
EAR_m2="$script_name terminated."
EMAIL_MSG "FATAL ERROR (Function): $EAR_ID" \
"${sp}$EAR_m1" \
"${sp}$EAR_m2"
if [ $EAR_opt_l -eq 1 ]; then
WRITE_ERR_TO_SYSLOGS -p "$EAR_pri" -t "$EAR_tag" \
"BATCH $EAR_ID $EAR_m1 $EAR_m2"
fi
EXIT 1;
fi
} # EAR_CREATE_FILE() #
#----------------------------------------------------------------#
#------------------------------------------------------------#
# If we still have arguments (optional/replacement message), #
# then use that message, else use the default. #
#------------------------------------------------------------#
[ $# -eq 0 ] && EAR_subj="NOTICE:" || EAR_subj=$*
#--------------------------------------------------------------------#
# If we have what looks like a good $active_status_file, then see #
# if the PID in that file is running (in the process queue). If #
# it is in the process queue, then life is good. However, if that #
# process is not running, then we take over those duties--beginning #
# by creating a new $active_status_file. #
#--------------------------------------------------------------------#
if [ ."$active_status_file" != . ]; then
if [ -s $active_status_file ]; then # Non zero-length file
EAR_pid=`sed -n 1p $active_status_file` # Get PID from file
ps $EAR_ps_opts \
| $AWK -v pid=$EAR_pid -v sp="$sp" "$EAR_awk_scr" # No $teelog
if [ $? -gt 0 ]; then
EAR_m1="Cancelling $script_name ($$)."
EAR_m2="PID $EAR_pid already running."
EMAIL_MSG "$EAR_ID $EAR_subj" \
"${sp}$EAR_m1" \
"${sp}Found active status file, $active_status_file." \
"${sp}$EAR_m2"
EXIT 1
else # Got an active status file, but process not running.
EMAIL_MSG "$EAR_ID $EAR_subj" \
"${sp}Active status file found, but $script_name" \
"${sp}(PID=$EAR_pid) NOT found in process queue." \
"${sp}Continuing $script_name."
EAR_CREATE_FILE
return 0 # All's well (it's our own PID)
fi
elif [ -f $active_status_file ]; then # File exists, but is empty.
EMAIL_MSG "$EAR_ID $EAR_subj" \
"${sp}$EAR_m1" \
"${sp}Found EMPTY active status file, $active_status_file." \
"${sp}$EAR_m2"
if [ $EAR_opt_l -eq 1 ]; then # Logger option? (1 = yes)
WRITE_ERR_TO_SYSLOGS -p "$EAR_pri" -t "$EAR_tag" \
"$EAR_ID $EAR_subj $EAR_m1 $EAR_m2"
fi
EXIT 1
else
EAR_CREATE_FILE
if [ $? -eq 0 ]; then
return 0 # Ah, the sweet smell of success.
else
EAR_m1="Problem creating $active_status_file!"
EAR_m2="$script_name terminated."
EMAIL_MSG "FATAL ERROR: $EAR_ID" \
"${sp}$EAR_m1" \
"${sp}$EAR_m2"
if [ $EAR_opt_l -eq 1 ]; then
WRITE_ERR_TO_SYSLOGS -p "$EAR_pri" -t "$EAR_tag" \
"BATCH $EAR_ID $EAR_m1 $EAR_m2"
fi
EXIT 1
fi
fi
else
EAR_m1="active_status_file variable NOT assigned!"
EAR_m2="$script_name terminated."
EMAIL_MSG "FATAL ERROR: $EAR_ID" \
"${sp}$EAR_m1" \
"${sp}$EAR_m2"
if [ $EAR_opt_l -eq 1 ]; then
WRITE_ERR_TO_SYSLOGS -p "$EAR_pri" -t "$EAR_tag" \
"BATCH $EAR_ID $EAR_m1 $EAR_m2"
fi
EXIT 1
fi
} # "EAR_" prefix identifies this function's local variables.
fi
#======================================================================#
# D O C U M E N T A T I O N #
#======================================================================#
# #
# Author: Bob Orlando #
# #
# Date: April 7, 1997 #
# #
# Program ID: exit_if_already_running.sh #
# #
# Usage: EXIT_IF_ALREADY_RUNNING [-l [-p priority] [-t tag]] #
# [optional/replacement subject] #
# #
# -l = Notify via logger command #
# (default is false) #
# -p = logger priority string #
# (default is "user.err") #
# -t = logger tag string #
# (default is "$LOGNAME[$$]") #
# #
# Option notes: Option (-l) MUST precede -p and -t. #
# #
# Purpose: Exit if the current process is already running. #
# #
# Description: If the script calling us is already running, then we #
# don't start a new one, providing we find the process #
# ID (held in the active status file) is actually in the #
# process (ps) queue. If the PID is not among 'ps' #
# output, we report that fact, put our PID in the active #
# status file, and continue. If the process is indeed #
# running, we notify responsible parties of its presence #
# and exit (terminating the calling program). #
# #
# Globals: Tests for presence of variable $active_status_file #
# and the file to which it points. #
# "EAR_" prefix identifies local function variables. #
# #
# Calls: EMAIL_MSG and EXIT library functions. #
# Optionally, WRITE_ERR_TO_SYSLOGS is also called. #
# #
# Exit_status: Success if no active status file exists and this #
# function is able to create one. Otherwise, we exit #
# with nonzero status. #
# #
# Notes: ..................................................... #
# ..................................................... #
# #
# Modified: 2004-04-02 Bob Orlando #
# v1.17 * Expand $AWK testing and assignment. #
# #
# 2004-03-03 Bob Orlando #
# v1.16 * Change set|egrep|awk to just set|egrep. #
# #
#----------------------------------------------------------------------#
|