I came across an interesting issue at work today. We have a PHP script which monitors a socket on our phone system to save call logs into a database. It’s pretty simple, but it needs to run constantly to catch all the phone calls going through the system. So I did some goggling and found a helpful little bash script:

#!/bin/bashPIDFILE=/tmp/phonemonitor.pidPHPSCRIPT=/usr/local/phonemonitor/monitor.phpecho 'Checking if our monitor script is active'if [ -f $PIDFILE ] ; then    PID=`cat $PIDFILE`    if ps ax | grep -v grep | grep $PID > /dev/null    then        echo "Script is running"    else        echo "Script is not running - attempting to Start"        rm -f $PIDFILE        php $PHPSCRIPT & echo $! > $PIDFILE&    fielse    echo "Script is not running - attempting to Start"    php $PHPSCRIPT & echo $! > $PIDFILE&fi

However, we recently noticed that phone calls weren’t being logged for around a week. Checking the server, the CRON was still set up and running the script produced the friendly “Script is running” message. But checking the process list for the script produced nothing.

Then it occurred to us that the process ID of the script was ‘8325’, and there was another process running with a process ID of ‘18325′. Subtle difference, but one that was confusing the script.

Luckily the fix for this is a piece of cake, simply check for the process ID surrounded with spaces:

if ps ax | grep -v grep | grep " ${PID} " > /dev/null

Resulting in this script:

#!/bin/bashPIDFILE=/tmp/phonemonitor.pidPHPSCRIPT=/usr/local/phonemonitor/monitor.phpecho 'Checking if our monitor script is active'if [ -f $PIDFILE ] ; then    PID=`cat $PIDFILE`    if ps ax | grep -v grep | grep " ${PID} " > /dev/null    then        echo "Script is running"    else        echo "Script is not running - attempting to Start"        rm -f $PIDFILE        php $PHPSCRIPT & echo $! > $PIDFILE&    fielse    echo "Script is not running - attempting to Start"    php $PHPSCRIPT & echo $! > $PIDFILE&fi

Done 🙂

I know there are better solutions, and I recently found out about the fantastic run-one utility by Dustin Kirkland, but the box I am running this on is an old CentOS 4 box and I needed to get phone logging working quickly, rather than stuff around upgrading servers and installing scripts.

Update:

Ozzie from my work has given me an even nicer fix for the problem. His solution doesn’t rely on the process list and grep, but instead checks for the process directory:

if [ -d "/proc/`cat $PIDFILE`" ]; then

Resulting in this:

#!/bin/bashPIDFILE=/tmp/phonemonitor.pidPHPSCRIPT=/usr/local/phonemonitor/monitor.phpecho 'Checking if our monitor script is active'if [ -f $PIDFILE ] ; then    if [ -d "/proc/`cat $PIDFILE`" ]; then        echo "Script is running"    else        echo "Script is not running - attempting to Start"        rm -f $PIDFILE        php $PHPSCRIPT & echo $! > $PIDFILE&    fielse    echo "Script is not running - attempting to Start"    php $PHPSCRIPT & echo $! > $PIDFILE&fi

This one is a nicer solution as it doesn’t rely on grep and spaces around the process ID.