複数のコマンドを同時に実行したいので、
以下のようなコードを書きました。
[ソース measure.rb]
def measure(count)
system("vmstat 1 #{count} > vm.log &")
system("iostat 1 #{count} > io.log &")
end
measure 0
[コマンドライン]
$ ruby measure.rb
この手の時間と回数を指定するようなコマンドは、
回数に「0」を指定すると無限回の繰り返しになります。
このような場合、通常 Ctrl+C で止めると思うのですが、
バックグラウンドで実行しているために
標準入力からのCtrl+CをRubyで受け取る方法がわかりません。
また、受信できたとしてもバックグラウンドのジョブに対して
Ctrl+C を送る方法もわかりません。
まとめると、知りたいことは以下の2点です。
1. Rubyスクリプトで、標準入力からの Ctrl+C を受け取る方法
2. バックグラウンドで実行しているジョブに、RubyからCtrl+Cを送る方法
可能であれば、実装例などもあるとうれしいです。
環境が書いていないですが、Ctrl+CということはUNIX,Linux,BSD,Mac辺りでしょうか?
取り敢えず上記環境ということで話を進めます。
とりあえずシンプルな方法で。
#!/usr/bin/env ruby def measure(count) system("vmstat 1 > vm.log &") end begin measure(ARGV.shift) while 1 sleep 1 end rescue SignalException puts "rescue #$!" system("pkill vmstat") system("ps aux|grep vmstat") end
1. Rubyスクリプトで、標準入力からの Ctrl+C を受け取る方法 2. バックグラウンドで実行しているジョブに、RubyからCtrl+Cを送る方法
この文章から想像するに、Ctrl+Cとは何かを知らないのでしょうか?
この辺りを簡単に説明しますと、Unix系OSにはシグナルという概念があります。
簡単にいえば、例外イベントをプロセスに対して送信するメッセージの様な物と考えてください。
詳しく解説すると大変なので、後はご自分で調べるか以下を参照してください。
http://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%B0%E3%83%8A%E3%83%A...(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)
http://codezine.jp/a/article/aid/1450.aspx
リンク先にあるようにCtrl+CはSIGINTというシグナルを発生させます。
さて、本題ですが、Rubyではスクリプト自身がシグナルを受けると例外のSignalExceptionが発生します。
ここがbegin〜endまでの処理です。
また、例外を受け取るとバックグラウンドで起動しているプロセスに対してもシグナルを送らないといけません。
ここがsystem("pkill vmstat")の部分です。
ちなみに、system("ps aux|grep vmstat")はきちんとプロセスが死んだか確認のために入れいています。
知りたかったことがよくわかりました!
SignalExceptionというものがあるのですね。
どうもありがとうございました。