5

有没有一种简单的方法来判断一个 ruby​​ 脚本是否已经在运行,然后适当地处理它?例如:我有一个名为 real_long_script.rb 的脚本。我让它每 5 分钟运行一次。当它运行时,我想看看之前的运行是否还在运行,然后停止执行第二个脚本。有任何想法吗?

4

4 回答 4

9

ps 是一种非常糟糕的方法,并且可能对竞争条件开放。

传统的 Unix/Linux 方法是将 PID 写入文件(通常在 /var/run 中)并在启动时检查该文件是否存在。

例如 pidfile 位于 /var/run/myscript.pid 然后你会在运行程序之前检查它是否存在。有一些技巧可以避免涉及使用 O_EXCL(排除锁定)打开文件和符号链接的竞争条件。

无论多么不可能,您都应该尝试通过在文件系统上使用原子操作来编写代码以避免竞争条件。

为了避免重新发明轮子,您可能需要查看http://rubyforge.org/projects/pidify/

于 2008-09-01T17:52:38.153 回答
1

您可能还应该检查该进程是否实际正在运行,这样如果您的脚本在没有清理自己的情况下死亡,它将在下一次运行,而不是简单地检查 /var/run/foo.pid 是否存在并退出。

于 2008-09-01T18:18:23.957 回答
1

汉兰达

描述

确保只有一个主脚本实例正在运行的 gem。简而言之,只能有一个。

安装

gem install highlander

概要

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

同时,回到命令行...

# 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

笔记

只需要求 highlander gem 即可确保只有该脚本的一个实例无法再次启动。如果您尝试再次启动它,它将引发 RuntimeError。

于 2015-06-25T07:41:24.070 回答
0

在 bash 中:

if ps aux | grep really_long_script.rb | grep -vq grep
then
    echo Script already running
else
    ruby really_long_script.rb
fi
于 2008-09-01T17:45:22.460 回答