I have a script that does an ftp from a SCO UNIX server to windows server to get files from the windows server. The script is set in the cron to run every xx minutes. Sometimes the script will hang and leave a process running. This can bog down the UNIX server. I want to be able to do two things. 1. I want to make sure that the script doesn’t hang – so it should terminate after xx minutes (the files are very small that it is getting). And 2. I want the script to test to make sure that it is not already running, before starting again. THANKS
A classic solution to this is to create a “semaphore” file, something like this at the beginning of the script:
then at the end of the script you delete it:
(or, if you want to be more fancy, use the trap command to specify that on exit condition 0 the temp file should be deleted: “trap “rm /tmp/program.lock” 0″)
One more nuance is that it needs to test to see if the file already exists, and decide what to do if the process is still running. That can be done with a straightforward test:
# the lock file already exists, so what to do?
if [ “$(ps -p `cat /tmp/program.lock` | wc -l)” -gt 1 ]; then
# process is still running
echo “$0: quit at start: lingering process `cat /tmp/program.lock`”
exit 0
else
# process not running, but lock file not deleted?
echo ” $0: orphan lock file warning. Lock file deleted.”
rm /tmp/program.lock
fi
fi
Alright, that’s not entire straightforward, but I think you can see how I would try to solve this problem. If you believe that XX minutes later the script SHOULD be done and the process should be killed if it’s still running, then you can do something like this:
or, if you want to be more aggressive, use:
To have a kill timer on the script, btw, write a separate little script that just waits xx seconds using the sleep command, then tries to do the kill shown above. Either it’ll error out, in which case the script is no longer running, or it’ll kill the script.
Hope that helps you out!
Alternative, script around pidof. Should man pidof to verify behavior on your system.
I prefer never to /dev/null any program, but pidof doesn’t like to be quiet.
Example (bashisms intended!):
#!/bin/bash
me=$(basename $0)
pidof -x -o ‘%PPID’ $me > /dev/null 2>&1 && exit 1
echo $me
sleep 300
Well, a rather different problem is the following: We want a program, say “perl /home/me/mydir/myscript.pl” to run continously, and to be restarted should it be stopped by a system failure
, a reboot, a power outage or whatever.
So we put in /etc/inittab a line like
myscr:3456:respawn:/home/me/myscr
and myscr reads
“cd /home/me/mydir;
perl /home/me/mydir/myscript.pl > /dev/null &”
however, this will respawn when myscr dies, not when the perl script dies. Consequently, it will
respawn zillions of perl /home/me/mydir/myscript.pl processes and
eventually put the system to a standstill.
What needs to be done is to check if myscript.pl
is running and only if it is not call it.
In this case I doubt we can use the solution posted above and hence avoid doing a ps -ef | grep myscript.pl and need to excluded the grep from there), and I am not sure what the most elegant way to do the checking would be
Ken, you’re right! That should indeed be “echo $$” not “cat $$”. Mea culpa! 🙂
Do you mean “echo $$” rather than “cat $$”?
I think this text in general is usefull, however, be very carefull (or actualy do not do it at all!) kill processes without checking if it is the correct process.
Another process might have taken your process ID and you may kill the wrong process, a check if the process is the program you are running should be done at all times!)