Finding the age of a unix process, killing old processes, killing zombie processes

I had issues with processes locking up. This script checks for processes and kills them if they are older than a certain time.

Its uses some functions you'll need to define or remove, like slog() which I use for logging, and is_running() which checks if this script is already running so you can add it to cron without running multiple copies.

Hope this helps someone :wink:

Jack.

#!/usr/bin/php
<?
    if (is_running()) die();

    slog("monitor started",2);

    while(true){
        check_process("convert"); // kill convert processes over 5 minutes old (default)
        check_process("bash",1440); // kill bash processes over 1440 minutes old
        check_process("qmail-smtpd",30); // kill qmail-smtpd processes over 30 minutes old
        sleep(300);
    }

    function cmd($cmd){
        $fp = popen($cmd, 'r');
        $ret="";
        while ($read = fread($fp, 2096)) $ret = $ret.$read;
        pclose($fp);
        return $ret;
    }
    function kill_pid($pid){
        slog("kill_pid: killing [$pid]",2);
        posix_kill($pid,1);
    }
    function check_process($cmd,$max_runtime=5) {
        $now = getdate();
        $h = $now['hours'];
        $m = $now['minutes'];
        $nowtime = ($h*3600)+($m*60);
        $x = cmd("ps h -fC $cmd");
        if ($x){
            $x = explode("\n",$x);
            foreach($x as $l){
                if ($l){
                    while (strstr($l,"  ")) $l = str_replace("  "," ",$l);
                    list($owner,$pid,$ppid,$c,$stime,$tty,$s,$time,$cmd) = explode(" ",$l);
                    if (!strstr($stime,":")) {
                        slog("check_process: $cmd : STIME [$stime] - more than a day old",2);
                        kill_pid($pid);
                    } else {
                        slog("check_process: $cmd : check runtime");
                        list($sh,$sm) = explode(":",$stime);
                        $runtime = ($sh*3600)+($sm*60);
                        $diff = ($nowtime - $runtime)/60;
                        if ($diff>$max_runtime){
                            slog("check_process: $cmd : STIME [$stime] now [$h:$m] - over $max_runtime minutes since start",2);
                            kill_pid($pid);
                        } else slog("check_process: $cmd : STIME [$stime] now [$h:$m] - running $diff/$max_runtime minutes",2);
                    }
                }
            }
        } else slog("check_process: $cmd : no processes",2);
    }
?>