# SccsId[] = "%W% (USL function) %G%"
EPC_name="EXIT_ON_PROCESS_CONFLICTS"
if [ ".${SECONDS}" = "." ]; then # Bourne function already loaded?
[ ."`set|egrep '^$EPC_name\(\)\{$'`" != . ] && EPC_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 '/^'$EPC_name'[=\(]?/'`" != . ] && EPC_loaded=1
else # Linux
[ ."`typeset -F|awk '/^'$EPC_name'[=\(]?/'`" != . ] && EPC_loaded=1
fi
fi
if [ 0${EPC_loaded} -eq 0 ]; then
#----------------------------------------------------------------------#
EXIT_ON_PROCESS_CONFLICTS() # 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:=" "}
: ${dashes:="------------------------------------------------------"}
: ${tmp:=/var/tmp}
if [ ."$log" = . ]; then
log=$name_root.log
[ ."$teelog" = . ] && teelog="cat"
fi
EPC_ID="$script_name($EPC_name)"
#----------------------------#
# Parse any function options.#
#----------------------------#
EPC_option=0
EPC_opt_f=""
EPC_fileid=""
EPC_opt_l=0
EPC_opt_p=0
EPC_opt_t=0
EPC_pri="$logger_p" # $logger_p and $logger_t are assigned defaults
EPC_tag="$logger_t" # within library defaults.sh.
EPC_root=$tmp/$name_root"_EPC_go_"$id_hex
EPC_err=$EPC_root"."$Xtimestamp
while getopts f:lp:t: EPC_opt 2>> $EPC_err
do
case $EPC_opt in
f ) EPC_opt_f="-f"
EPC_fileid="$OPTARG"
;;
l ) EPC_opt_l=1
;;
p ) EPC_opt_p=1
EPC_pri="$OPTARG"
EPC_option=1
;;
t ) EPC_opt_t=1
EPC_tag="$OPTARG"
EPC_option=1
;;
\? ) echo "$EPC_ID" \
"Invalid option: -`sed 's/^.*-- //' $EPC_err`" 1>&2
;;
* ) ;;
esac
done
[ $EPC_option -ne 0 ] && shift `expr $OPTIND - 1` # Shift past options to remaining args
[ ."$EPC_root" != . ] && \rm -f $EPC_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). #
#----------------------------------------------------------------#
#--------------------------------------------------------------------#
# Validate options and arguments. Nawk returns nonzero on failure #
# or zero if all is well. If there is no problem, then EPC_programs.#
# will contain all the programs found in the contentions programs #
# file (plus any added to the command line). ELse, EPC_programs #
# will have an error message followed by usage text. #
#--------------------------------------------------------------------#
EPC_procs=`$AWK -v sp="$sp" \
-v EPC_name="$EPC_name" \
-v script_name="$script_name" \
'BEGIN \
{
if (ARGC < 2)
{
print sp"Insufficient args.\n"
exit_usage()
}
if (ARGV[1] == "-f")
{
if (ARGC > 2) # ARGV[0], 1, 2 = progname, -f, fileid
{
#----------------------------------------#
# If file is specified, but missing ... #
#----------------------------------------#
status = getline line <ARGV[2]
if (status == -1)
{
print sp"File option specified, but "ARGV[2],
"\n"sp"is missing or non-existent.\n"
exit_usage()
}
#----------------------------------------#
# There is no problem if file is empty. #
#----------------------------------------#
if (status == 0)
{
print sp""ARGV[2]" contains no contentious",
"progcesses (which may or may not be normal)."
exit 251
}
#------------------------------------------#
# We should have one arg left, the fileid. #
# If no, then fuss at the user and exit. #
# Else assign n (for use in ARGV[n]. #
#------------------------------------------#
shift 2
n = ARGC - 2
if (n < 1)
{
print sp"Insufficient args after shift.\n"
print sp"We were expecting a fileid.\n"
exit_usage()
}
n = 3 # Point past filelist argument
#------------------------------------------------#
# The do-while allows us to print the first line #
# (already read from the file list), then print #
# the remaining arguments. #
#------------------------------------------------#
do {
sub(/#.*/,"",line)
if (line !~ /^$/) printf("%s ",line) # No \n
} while (getline line <ARGV[2] > 0)
#------------------------------------------------#
# In case the user also appended other processes #
# (in addition to those specified in the file), #
# print them as well. #
#------------------------------------------------#
for (; n < ARGC; n++)
if (ARGV[n] !~ /^$/) printf("%s ",ARGV[n]) # No \n
exit 0
}
else
{
print sp"File option specified, but fileid omitted!"
exit_usage()
}
}
else
{
#---------------------------------------------------#
# -f option not specified, so the args must be a #
# list of contentions processes--so print each one. #
#---------------------------------------------------#
for (n = 1; n < ARGC; n++)
if (ARGV[n] !~ /^$/) printf("%s ",ARGV[n]) # No \n
exit 0
}
#------------------------------------------------------#
# Failsafe. If we get here, I have an unknown error. #
#------------------------------------------------------#
print sp"Unknown error "EPC_name"(awk)!"
exit_usage()
} # E.O.BEGIN
#--------------------------------------------------------#
function exit_usage()
#--------------------------------------------------------#
{
print sp"Usage: EPC_name [-l [-p priority] [-t tag]]" ,
"\n"sp" [-f fileid] process ...\n" ,
"\n"sp" -l = Notify via logger command" ,
"\n"sp" (default is false)" ,
"\n"sp" -p = logger priority string" ,
"\n"sp" (default is \047user.err\047)" ,
"\n"sp" -t = logger tag string" ,
"\n"sp" (default is \047$LOGNAME[$$]\047)" ,
"\n"sp" -f indicates that the following fileid" ,
"\n"sp" contains a list of contentious" ,
"\n"sp" programs/processes.\n" ,
"\n"sp" \047process ...\047 are process name(s) that",
"\n"sp" we\047re to test for (these may be in",
"\n"sp" addition to those contained in" ,
"\n"sp" fileid).\n" ,
"\n"sp"Purpose: Exit if contentious processes are found" ,
"\n"sp" running.\n" ,
"\n"sp""script_name" terminated.\n"
exit 252
}' $EPC_opt_f $EPC_fileid "$@" 2>&1`
EPC_status=$?
#--------------------------------------------------------------------#
# If status is 252, we have a problem, so fuss at the user and exit. #
# #
# If status is 251, then there's really no problem (there simply are #
# no programs listed in the contentious programs file). #
# #
# If status is something other than zero, then possibly nawk has #
# some other problem (we use 251 and 252 above in the hope of #
# keeping our errors separate from nawk's). #
# #
# Finally, if the status is zero we drop thru and check for #
# processes running that match our list ($EPC_programs). #
#--------------------------------------------------------------------#
if [ $EPC_status -eq 252 ]; then
EPC_errmsg="FATAL ERROR: $EPC_ID"
EMAIL_MSG "$EPC_errmsg" \
"$EPC_procs"
if [ $EPC_opt_l -eq 1 ]; then # Logger option? (1 = yes)
WRITE_ERR_TO_SYSLOGS -p "$EPC_pri" -t "$EPC_tag" \
"'ABORT: $EPC_errmsg $EPC_procs'"
fi
EXIT 1
elif [ $EPC_status -eq 251 ]; then
echo "$EPC_procs" | $teelog
return 0 # No programs listed in contentious programs file.
elif [ $EPC_status -ne 0 ]; then
EPC_errmsg="FATAL ERROR (Unknown): $EPC_ID"
EMAIL_MSG "$EPC_errmsg" \
"${sp}Awk status=$EPC_status. Awk's output follows:" \
"${sp}$dashes" \
"$EPC_procs" \
"${sp}$dashes"
if [ $EPC_opt_l -eq 1 ]; then # Logger option? (1 = yes)
WRITE_ERR_TO_SYSLOGS -p "$EPC_pri" -t "$EPC_tag" \
"$EPC_procs $EPC_procs"
fi
EXIT 1
fi
#------------------------------------------------------#
# Loop thru each arg, testing for each program (arg). #
#------------------------------------------------------#
EPC_ps_line=`ps -eaf|$AWK -v procs="$EPC_procs" \
'BEGIN \
{
proc_running=0 # Initially false
n = split(procs,proc_array," ")
}
{ #---------------------------#
for (i=1; i <= n; i++) # For each line returned #
{ # by "ps", we loop through #
proc = proc_array[i] # our list of contentions #
vi = "vi "proc # processes, exiting as #
self = "awk -v procs="proc # soon as we discover even #
if ($0 ~ proc) # even one. #
{ #---------------------------#
gsub( /[\t ]+/," ",$0) # Squeeze whitespace
gsub(/^[\t ]+/,"", $0) # Remove leading spaces
if ($0 ~ vi || $0 ~ self) next # Check the next one.
sub(proc_array[i],"=>> "proc_array[i]" <<=")
proc_running = 1 # true
exit # Leaves "action" section and goes to END
}
}
}
END \
{
print $0
exit proc_running # true | false
}' 2>&1`
if [ $? -eq 1 ]; then
EPC_errmsg="FATAL ERROR: $script_name"
EPC_m1="Possible contention with the following process:"
EPC_m2="$EPC_ps_line."
EPC_m3="$script_name terminated."
EMAIL_MSG "$EPC_errmsg" \
"${sp}$EPC_m1" \
"${sp}$EPC_m2" \
"${sp}$EPC_m3"
if [ $EPC_opt_l -eq 1 ]; then # Logger option? (1 = yes)
WRITE_ERR_TO_SYSLOGS -p "$EPC_pri" -t "$EPC_tag" \
"$EPC_errmsg $EPC_m1 $EPC_m2 $EPC_m3"
fi
EXIT 1
fi
} # "EPC_" 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: December 14, 1996 #
# #
# Program ID: exit_on_process_conflicts.sh #
# #
# Usage: EXIT_ON_PROCESS_CONFLICTS [-l [-p priority] [-t tag]] #
# [-f fileid] process ... #
# #
# -l = Notify via logger command #
# (default is false) #
# -p = logger priority string #
# (default is "user.err") #
# -t = logger tag string #
# (default is "$LOGNAME[$$]") #
# -f = the fileid that follows contains #
# a list of contentious programs. #
# #
# "process ..." are process name(s) that we #
# are to test for (these may be in addition #
# to those contained in fileid). #
# #
# Option notes: Option (-l) MUST precede -p and -t. #
# #
# Purpose: Query current processes (ps -eaf) reporting any #
# contentious processes that are currently running #
# (found in our argument list), and exiting if any are #
# found. Edits (vi) of unqualified/unpathed programs #
# are not counted as running; however, edits of fully #
# qualified (pathed) process names are counted. #
# (This information is handy for shutting down those #
# processes which test for contentious programs.) #
# #
# Globals: No global variables assigned from this function. #
# "EPC_" prefix identifies local function variables. #
# #
# Calls: EMAIL_MSG and EXIT library functions. #
# #
# Exit_status: Exits with failure (1) on error, or on finding a #
# contentious program/process. #
# #
# Notes: Although error notification is via EMAIL_MSG library #
# function, the report of processes in contention is #
# displayed via stdout only. It is up to the caller #
# to capture and use that output as needed. #
# #
# Modified: 2004-04-02 Bob Orlando #
# v1.13 * Expand $AWK testing and assignment. #
# #
# 2004-03-03 Bob Orlando #
# v1.12 * Change set|egrep|awk to just set|egrep. #
# #
#----------------------------------------------------------------------#
|