Rubyで外部コマンドを実行して結果を受け取る方法あれこれ

  • 530
    いいね
  • 5
    コメント
この記事は最終更新日から1年以上が経過しています。

全て Windows でも使えます

$ ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410)

Kernel.#system

サクッと実行したい場合に便利
実行結果(true, false, nil)が返却される

stdin : 渡せない
stdout : 取れない
stderr : 取れない
status : 取れる($? で参照)

system('mkdir hoge') # => true

バッククォート

サクッと実行して、標準出力の内容だけ取れればOKな場合に便利
標準出力が返却される

stdin : 渡せない
stdout : 取れる
stderr : 取れない
status : 取れる($? で参照)

`date` # => "2012年 9月 3日 月曜日 23時59分17秒 JST\n"
# %x[ date ] でも同じ

IO.popen

標準入力にデータを渡して標準出力から受け取りたい場合に使う
IOオブジェクトが返却される
実行できなかった場合は Errno::EXXX が発生する

stdin : 渡せる
stdout : 取れる
stderr : 取れる(コメント参照)
status : 取れる($? で参照)

p IO.popen("cat", "r+") {|io|
  io.puts "foo"
  io.close_write
  io.gets
}
# => "foo\n"

Open3.capture3

標準入出力を使ったデータのやりとりを簡単に使いたい場合に便利
標準出力, 標準エラー, 終了ステータスが返却される
実行できなかった場合は Errno::EXXX が発生する

stdin : 渡せる
stdout : 取れる
stderr : 取れる
status : 取れる

require "open3"

o, e, s = Open3.capture3("echo a; sort >&2", :stdin_data=>"foo\nbar\nbaz\n")
p o #=> "a\n"
p e #=> "bar\nbaz\nfoo\n"
p s #=> #<Process::Status: pid 32682 exit 0>

Open3.popen3

実行中プロセスの標準出力、標準エラー出力をリアルタイムに扱いたい場合に便利
ブロックを渡すことで、実行中プロセスの標準出力、標準エラー出力を扱える

stdin : 渡せる
stdout : 取れる
stderr : 取れる
status : 取れる

require "open3"

Open3.popen3("echo a; sleep 1; echo b; sort >&2; sleep 3") do |i, o, e, w|
  i.write "foo\nbar\nbaz\n"
  i.close
  o.each do |line| p line end #=> "a\n",  "b\n"
  e.each do |line| p line end #=> "bar\n", "baz\n", "foo\n"
  p w.value #=> #<Process::Status: pid 32682 exit 0>
end

systemu

ブロック渡すとバックグラウンド実行してくれたりして色々便利
終了ステータス, 標準出力, 標準エラーが返却される

stdin : 渡せる
stdout : 取れる
stderr : 取れる
status : 取れる

require 'systemu'
date = %q( ruby -e"  t = Time.now; STDOUT.puts t; STDERR.puts t  " )
status, stdout, stderr = systemu date
p [ status, stdout, stderr ]
# => [#<Process::Status: pid 50931 exit 0>, "2011-12-11 22:07:30 -0700\n", "2011-12-11 22:07:30 -0700\n"]

参考

http://doc.ruby-lang.org/ja/1.9.3/doc/method/Kernel/m/system
http://doc.ruby-lang.org/ja/1.9.3/doc/spec=2fliteral.html#command
http://doc.ruby-lang.org/ja/1.9.3/method/IO/s/popen.html
http://doc.ruby-lang.org/ja/1.9.3/method/Open3/m/capture3.html
http://doc.ruby-lang.org/ja/1.9.3/method/Open3/m/popen3.html
https://github.com/ahoward/systemu
http://d.hatena.ne.jp/ursm/20090625/1245947107