LoginSignup
706
652

More than 5 years have passed since last update.

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

Last updated at Posted at 2012-12-26

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

706
652
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
706
652