tags:

views:

72

answers:

4

Hello,

As a way to build a poor-man's watchdog and make sure an application is restarted in case it crashes (until I figure out why), I need to write a PHP CLI script that will be run by cron every 5mn to check whether the process is still running.

Based on this page, I tried the following code, but it always returns True even if I call it with bogus data:

function processExists($file = false) {
    $exists= false;
    $file= $file ? $file : __FILE__;

    // Check if file is in process list
    exec("ps -C $file -o pid=", $pids);
    if (count($pids) > 1) {
    $exists = true;
    }
    return $exists;
}

#if(processExists("lighttpd"))
if(processExists("dummy"))
    print("Exists\n")
else
    print("Doesn't exist\n");

Next, I tried this code...

(exec("ps -A | grep -i 'lighttpd -D' | grep -v grep", $output);)
print $output;

... but don't get what I expect:

/tmp> ./mycron.phpcli 
Arrayroot:/tmp> 

FWIW, this script is run with the CLI version of PHP 5.2.5, and the OS is uClinux 2.6.19.3.

Thank you for any hint.


Edit: This seems to work fine

exec("ps aux | grep -i 'lighttpd -D' | grep -v grep", $pids);
if(empty($pids)) {
        print "Lighttpd not running!\n";
} else {
        print "Lighttpd OK\n";
}
A: 

You can try this, which combines bits of those two approaches:

function processExists($processName) {
    $exists= false;
    exec("ps -A | grep -i $processName | grep -v grep", $pids);
    if (count($pids) > 0) {
        $exists = true;
    }
    return $exists;
}

If that doesn't work, you may want to just try running the ps command on your system and seeing what output it gives.

john
+1  A: 

I'd use pgrep to do this (caution, untested code):


exec("pgrep lighttpd", $pids);
if(empty($pids)) {

    // lighttpd is not running!
}

I have a bash script that does something similar (but with SSH tunnels):


#!/bin/sh

MYSQL_TUNNEL="ssh -f -N -L 33060:127.0.0.1:3306 tunnel@db"
RSYNC_TUNNEL="ssh -f -N -L 8730:127.0.0.1:873 tunnel@db"

# MYSQL
if [ -z `pgrep -f -x "$MYSQL_TUNNEL"` ] 
then
    echo Creating tunnel for MySQL.
    $MYSQL_TUNNEL
fi

# RSYNC
if [ -z `pgrep -f -x "$RSYNC_TUNNEL"` ]
then
    echo Creating tunnel for rsync.
    $RSYNC_TUNNEL
fi


You could alter this script with the commands that you want to monitor.

mmattax
Thanks everyone. Calling exec() with grep (pgrep isn't available on the embedded device I'm running this) seems to do the job.
A: 

i have a function to get the pid of a process...

function getRunningPid($processName) {
    $pid = 0;
    $processes = array();
    $command = 'ps ax | grep '.$processName;
    exec($command, $processes);
    foreach ($processes as $processString) {
        $processArr = explode(' ', trim($processString));
            if (
            (intval($processArr[0]) != getmypid())&&
            (strpos($processString, 'grep '.$processName) === false)
        ) {
            $pid = intval($processArr[0]);
        }
    }
    return $pid;
}
kgb
Take a look at the pgrep command!
mmattax
A: 

If you're doing it in php, why not use php code:

In the running program:

define('PIDFILE', '/var/run/myfile.pid');

file_put_contents(PIDFILE, posix_getpid());
function removePidFile() {
    unlink(PIDFILE);
}
register_shutdown_function('removePidFile');   

Then, in the watchdog program, all you need to do is:

function isProcessRunning($pidFile = '/var/run/myfile.pid') {
    if (!file_exists($pidFile) || !is_file($pidFile)) return false;
    $pid = file_get_contents($pidFile);
    return posix_kill($pid, 0);
}

Basically, posix_kill has a special signal 0 that doesn't actually send a signal to the process, but it does check to see if a signal can be sent (the process is actually running).

And yes, I do use this quite often when I need long running (or at least watchable) php processes. Typically I write init scripts to start the PHP program, and then have a cron watchdog to check hourly to see if it's running (and if not restart it)...

ircmaxell