外部のコマンドを実行
exec
exec はコマンドの失敗時にエラーを返す他は何ら値を返しません。irb で実行するとこんな感じ。
irb(main):001:0> exec("ruby -v") ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]
そして irb は終了してしまいました。
system
system ではコマンドが成功すると true を、失敗すると false を返します。
irb(main):001:0> system("ruby -v") ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32] => true irb(main):002:0> system("open_sesami") => false
こちらは、外部の PHP モジュールと連携した例。
if system("php sample.php") p "正常終了です" else p "異常終了です" end
外部に処理を投げる時、処理結果を真偽値で受け取ればいいケースなどはこれで。
``
`` を利用すると外部から真偽値以外の値を直接受け取る事ができます。コマンドの失敗時には例外が発生し、値は返りません(nil になります)。
irb(main):001:0> a = `ruby -v` => "ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]\n" irb(main):002:0> p a "ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]\n" => nil
http://d.hatena.ne.jp/spitfire_tree/20080809/1218266645
外部の JAVA モジュールに引数を渡して、結果を受け取ったサンプル。
def download item = Item.find(params[:id]) if item # 引数を渡しつつ java のモジュールから値を受け取る data = `java MyImageCreator #{item.value}` if data send_data(data, :type => "application/something") end end end
実際の利用時にはエラー処理が必須でしょう。
なお、値を渡す側では標準出力に出力を行うように設定する必要があります。
IO.popen
これは、標準入出力を使って外部とやりとりをします。
cmd = "java test.java" # 実行するコマンド cin = "This is a dog." #標準入力に流すテキスト IO.popen(cmd, 'r+') do |pipe| pipe.write(cin) pipe.close_write p pipe.read end
バイナリデータを使うならこちら。PDF を受け取ってみたり。
cmd = "java iText.StreamToRubyMethodTest 1" IO.popen(cmd, 'r+') do |pipe| pipe.binmode byte_stream = pipe.read File.open("unk.pdf", 'wb') do |output| output.binmode output.write(byte_stream) output.close end end