tags:

views:

480

answers:

3

There are several ways to do this, but I'm not sure which one of them is the best.

Here's what I can think of:

  • Look for the process using pgrep.
  • Have the script lock itself using flock, and then check if it is locked each time it runs.
  • Create a pid file in /var/run/program_name.pid and check for existence, and compare pids if needed.

There are probably more ways to do this. What do you think is the best approach?

+7  A: 

Do the old PID file trick.

  • start process
  • see if there is a file called "myprog.PID"
  • if so, complain loudly and exit
  • if not, create a file called "myprog.PID" and then continue

HTH

cheers,

Rob

Rob Wells
This can be improved by reading the PID from the file and checking to see whether the process still exists (using kill 0, $pid). If not, then ignore the old pid file and proceed. This helps recover more gracefully from a crashed process.
Greg Hewgill
+1 for checking whether the pid found in the file exists, kill with signal 0 exists just for that.
Keltia
Note that this also has a race condition if two processes try to start at the same time, check for the file at the same, and neither file a pid file.
brian d foy
+18  A: 

There are many ways to do it. PID files are the traditional way to do it. You could also hold a lock on a file, for example the program itself. This small piece of code will do the trick:

use Fcntl ':flock';
open my $self, '<', $0 or die "Couldn't open self: $!";
flock $self, LOCK_EX | LOCK_NB or croak "This script is already running";

One advantage over PID files is that files automatically get unlocked when the program exits. It's much easier to implement in a reliable way.

Leon Timmermans
+1: simple, portable and no race conditions.
j_random_hacker
+1  A: 

All of the options that you list are fine. One thing with this though, is to be aware that in rare cases, you can end up with a process that runs for a very long time (i.e., stuck waiting on something). You might want to think about keeping an eye on how long the other running instance has been running and possibly send yourself an alert if it exceeds a certain amount of time (such as a day perhaps).

Scott Hoffman