Rubyについて質問です。


複数のコマンドを同時に実行したいので、
以下のようなコードを書きました。

[ソース 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を送る方法

可能であれば、実装例などもあるとうれしいです。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2008/01/24 08:48:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:longicorn No.1

回答回数56ベストアンサー獲得回数6

ポイント100pt

環境が書いていないですが、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")はきちんとプロセスが死んだか確認のために入れいています。

id:kanouk

知りたかったことがよくわかりました!

SignalExceptionというものがあるのですね。

どうもありがとうございました。

2008/01/24 08:47:33

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません