1

I found this interesting page that suggests several options:

  1. Create a lock file
  2. Create a PID file.
  3. flock
  4. solo

But what about his option:

Check ps to see if the executed command is currently running.

(A ps-check.sh script could even be included at the start of every cron job you create.)

I'm assuming that the reason I haven't come across this kind of solution is that it's a bad idea.

Why is this a bad idea?

ps-check.sh could return 1 if the command is already running. The cron script could call ps-check.sh like this:

#!/bin/bash
#some script

#get current script name into variable
#then use ps-check.sh to see if current script is already running
#by supplying it with 2 things: script name and current PID
me=`basename "$0"`    
if (( $(ps-check.sh $me $$) == 1)); then
  exit 1;
fi
# do more stuff

ps-check.sh would check to see if the script was already running under another PID.

Is there any case where a script would be running but not visible in ps? If sleeping?

EDIT - Conclusion:

I've decided to go with flock. Checking ps could work but I would probably have to handle a lot of conditions to make sure. I assume flock already handles most of those.

2 Answers2

2

The flaw in using ps logic is that you expect a process name to be unique.

Unless you always start your processes with an absolute path a different user (or you yourself) can easily create a completely different process with the same name that would prevent your cron job from running.

HBruijn
  • 84,206
  • 24
  • 145
  • 224
1

I would recommend using run-one command - much simpler than dealing with the locks. From the docs:

run-one is a wrapper script that runs no more than one unique instance of some command with a unique set of arguments. This is often useful with cronjobs, when you want no more than one copy running at a time.

run-this-one is exactly like run-one, except that it will use pgrep and kill to find and kill any running processes owned by the user and matching the target commands and arguments. Note that run-this-one will block while trying to kill matching processes, until all matching processes are dead.

run-one-constantly operates exactly like run-one except that it respawns "COMMAND [ARGS]" any time COMMAND exits (zero or non-zero).

keep-one-running is an alias for run-one-constantly.

run-one-until-success operates exactly like run-one-constantly except that it respawns "COMMAND [ARGS]" until COMMAND exits successfully (ie, exits zero).

run-one-until-failure operates exactly like run-one-constantly except that it respawns "COMMAND [ARGS]" until COMMAND exits with failure (ie, exits non-zero).