Cron job to prevent simultaneous script

I'm using a shared server on Hostgator (Linux CentOS). I'm trying to set a cron job using the Control Panel that will check if its already running before starting a new one.

I've tried the following...

* * * * * [ -z "$(ps ax|grep /pathtoscript/parse_script.php|grep -v grep)" ] && [ php /pathtoscript/parse_script.php ]

but I get this error emailed to me...

/bin/sh: line 0: [: php: unary operator expected

Any ideas how to make this work?

Hi.

Why are you testing this (as it looks like you're trying to):

&& [ php /pathtoscript/parse_script.php ]

and not just running it?

&& php /pathtoscript/parse_script.php

You may also need to provide the full path to the php binary.

Traditional way is to have the script create a file somewhere containing the process' PID, and check if the file's present and the PID's valid to see if it's still running. The start-stop-daemon utility can help simplify this.

Your way may work if you're only ever running one instance at a time, ever. You've got some extra [ ] there. Try this:

[ -z "$(ps ax|grep /pathtoscript/parse_script.php|grep -v grep)" ] && php /pathtoscript/parse_script.php

I removed the extra braces. I set it to run every 2 minutes like this.

*/2 * * * * [ -z "$(ps ax|grep /pathtoscript/parse_script.php|grep -v grep)" ] && php /pathtoscript/parse_script.php

Then after a couple minutes, there are 2 jobs running. Here's what I saw in the Control Panel...

PID    Process

20010    /bin/sh -c [ -z "$(ps ax|grep /pathtoscript/parse_script.php|grep -v grep)" ] && php /pathtoscript/parse_script.php    

22072    /bin/sh -c [ -z "$(ps ax|grep /pathtoscript/parse_script.php|grep -v grep)" ] && php /pathtoscript/parse_script.php

I checked my email and saw that the command failed...

/bin/sh: fork: Resource temporarily unavailable
/bin/sh: fork: Resource temporarily unavailable
grep: write error: Broken pipe

Most of the time this cron command works, but every so often, it fails. How could I change the command so that when the command gets an error, it simply does NOT execute the php script?

Wouldn't it be simpler, and more robust, to put the check (if the script is already running) in the script itself?

1 Like

I tried it in my script but wasn't getting results from exec statement, but now I have it working...

exec("ps  ax", $results)

Thanks for pointing me in the right direction.