Mike Farmer
Mike Farmer

Reputation: 2992

Determine if a ruby script is already running

Is there an easy way to tell if a ruby script is already running and then handle it appropriately? For example: I have a script called really_long_script.rb. I have it cronned to run every 5 minutes. When it runs, I want to see if the previous run is still running and then stop the execution of the second script. Any ideas?

Upvotes: 6

Views: 3058

Answers (4)

John La Rooy
John La Rooy

Reputation: 304195

Highlander

Description

A gem that ensures only one instance of your main script is running. In short, there can be only one.

Installation

gem install highlander

Synopsis

require 'highlander' # This should be the -first- thing in your code.
# Your code here

Meanwhile, back on the command line...

# First attempt, works. Assume it's running in the background.
ruby your_script.rb

# Second attempt while the first instance is still running, fails.
ruby your_script.rb # => RuntimeError

Notes

Simply requiring the highlander gem ensures that only one instance of that script cannot be started again. If you try to start it again it will raise a RuntimeError.

Upvotes: 2

Aaron Maenpaa
Aaron Maenpaa

Reputation: 122900

You should probably also check that the process is actually running, so that if your script dies without cleaning itself up, it will run the next time rather than simply checking that /var/run/foo.pid exists and exiting.

Upvotes: 1

Philip Reynolds
Philip Reynolds

Reputation: 9392

The ps is a really poor way of doing that and probably open to race conditions.

The traditional Unix/Linux way would be to write the PID to a file (typically in /var/run) and check to see if that file exists on startup.

e.g. the pidfile being located at /var/run/myscript.pid then you'd check to see if that exists before running the program. There are a few tricks to avoid race conditions involving using O_EXCL (exclusing locking) to open the file and symbolic links.

However unlikely, you should try to code to avoid race conditions by using atomic operations on the filesystem.

To save re-inventing the wheel, you might want to look at http://rubyforge.org/projects/pidify/

Upvotes: 9

Eli Courtwright
Eli Courtwright

Reputation: 192921

In bash:

if ps aux | grep really_long_script.rb | grep -vq grep
then
    echo Script already running
else
    ruby really_long_script.rb
fi

Upvotes: 0

Related Questions