ruby スクリプトが既に実行されているかどうかを確認し、適切に処理する簡単な方法はありますか? 例:really_long_script.rb というスクリプトがあります。5分ごとに実行するようにcron化しています。実行時に、前の実行がまだ実行されているかどうかを確認してから、2 番目のスクリプトの実行を停止したいと考えています。何か案は?
4 に答える
ps はそれを行うための非常に貧弱な方法であり、おそらく競合状態に陥ります。
従来の Unix/Linux の方法では、PID をファイル (通常は /var/run 内) に書き込み、起動時にそのファイルが存在するかどうかを確認します。
たとえば、pidfile が /var/run/myscript.pid にある場合、プログラムを実行する前にそれが存在するかどうかを確認します。O_EXCL (ロックを除く) を使用してファイルとシンボリック リンクを開くことを含む、競合状態を回避するためのいくつかのトリックがあります。
可能性は低いですが、ファイルシステムでアトミック操作を使用して競合状態を回避するようにコーディングするようにしてください。
車輪の再発明を省くために、http://rubyforge.org/projects/pidify/を参照してください。
おそらく、プロセスが実際に実行されていることも確認する必要があります。そうすれば、スクリプトがクリーンアップせずに終了した場合、単純に /var/run/foo.pid が存在することを確認して終了するのではなく、次回実行されるようになります。
ハイランダー
説明
メイン スクリプトのインスタンスが 1 つだけ実行されるようにする gem。要するに、存在できるのは 1 つだけです。
インストール
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 を単に要求するだけで、そのスクリプトの 1 つのインスタンスのみを再起動できないことが保証されます。もう一度開始しようとすると、RuntimeError が発生します。
バッシュで:
if ps aux | grep really_long_script.rb | grep -vq grep
then
echo Script already running
else
ruby really_long_script.rb
fi