Help us understand the problem. What is going on with this article?

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

tyabe
Rubyが好きなソフトウェアエンジニア。Shibuya.rb
storesjp
インターネットビジネスの企画・開発・運営、マーケティング、プロモーション、コンテンツの企画・制作
https://about.stores.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした