人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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を送る方法

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


●質問者: kenk
●カテゴリ:コンピュータ
✍キーワード:def Ruby VM コマンド コマンドライン
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● longicorn
●100ポイント ベストアンサー

環境が書いていないですが、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というものがあるのですね。

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

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ