Ruby

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

More than 3 years have passed since last update.

全て 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