Vous êtes sur la page 1sur 3

SCRIPTNAME=`basename $0` PIDFILE=/var/run/${SCRIPTNAME}.

pid if [ -f ${PIDFILE} ]; then #verify if the process is actually still running under this pid OLDPID=`cat ${PIDFILE}` RESULT=`ps -ef | grep ${OLDPID} | grep ${SCRIPTNAME}` if [ -n "${RESULT}" ]; then echo "Script already running! Exiting" exit 255 fi fi #grab pid of this process and update the pid file with it PID=`ps -ef | grep ${SCRIPTNAME} | head -n1 | awk ' {print $2;} '` echo ${PID} > ${PIDFILE} and at the end if [ -f ${PIDFILE} ]; then rm ${PIDFILE} fi mkdir "$LOCK" || { echo "Script already running" ; exit 1 ; } The other method is the noclobber option, set using set -C. This option forces t he shell to open files for output redirection with the O_EXCL flag. Use it like this: set -C > "$LOCK" || { echo "Script already running" ; exit 1 ; } set +C #!/bin/bash long_running_tool & echo $! > pid_file

#!/bin/bash echo $$ > fooapp.pid exec fooapp

#=== FUNCTION ================================================================ # NAME: pidfilename # DESCRIPTION: create a predictable pid file name, put it in the right inode # PARAMETERS: none # RETURNS: path and filename #=============================================================================== function pidfilename() { myfile=$(basename "$0" .sh) whoiam=$(whoami) mypidfile=/tmp/$myfile.pid [[ "$whoiam" == 'root' ]] && mypidfile=/var/run/$myfile.pid echo $mypidfile

} #=== FUNCTION ================================================================ # NAME: cleanup # DESCRIPTION: post service processing (clean temp space,pid files) # PARAMETERS: none # RETURNS: none #=============================================================================== function cleanup () { #Don't recurse in the exit trap trap - INT TERM EXIT #remove the pid file cleanly on exit [[ -f "$mypidfile" ]] && rm "$mypidfile" #add other post processing cleanup here exit } #=== FUNCTION ================================================================ # NAME: isrunning # DESCRIPTION: is any previous instance of this script already running # PARAMETERS: pidfile location # RETURNS: boolean 0|1 #=============================================================================== function isrunning() { pidfile="$1" [[ ! -f "$pidfile" ]] && return 1 #pid file is nonexistent procpid=$(<"$pidfile") [[ -z "$procpid" ]] && return 1 #pid file contains no pid # check process list for pid existence and is an instance of this script [[ ! $(ps -p $procpid | grep $(basename $0)) == "" ]] && value=0 || value=1 return $value } #=== FUNCTION ================================================================ # NAME: createpidfile # DESCRIPTION: atomic creation of pid file with no race condition # PARAMETERS: the pid to put in the file, the filename to use as a lock # RETURNS: none #=============================================================================== function createpidfile() { mypid=$1 pidfile=$2 #Close stderr, don't overwrite existing file, shove my pid in the lock file. $(exec 2>&-; set -o noclobber; echo "$mypid" > "$pidfile") [[ ! -f "$pidfile" ]] && exit #Lock file creation failed procpid=$(<"$pidfile") [[ $mypid -ne $procpid ]] && { #I'm not the pid in the lock file # Is the process pid in the lockfile still running? isrunning "$pidfile" || { # No. Kill the pidfile and relaunch ourselves properly. rm "$pidfile" $0 $@ & } exit } }

mypidfile=$(pidfilename) createpidfile $$ "$mypidfile" # I win! set a trap for the lockfile on exit trap 'cleanup' INT TERM EXIT # Go ahead and do some processing sleep 10 I have been informed that there are a few corner cases that this script does not !/bin/ksh # # Stop or start setiathome depending on current status. # Will not start process if file work_unit.sah is missing. # cd /usr/local/setiathome read pid < pid.sah pidcom=$(ps -hp $pid -o %c) es=$? if [[ $es = 0 && $pidcom = setiathome ]]; then kill $pid elif [[ -a work_unit.sah ]]; then ./setiathome -nice 19 > /dev/null 2> /dev/null & fi

Vous aimerez peut-être aussi