module function Open3.#popen3

popen3(*cmd) -> [IO, IO, IO, Thread][permalink][rdoc]
popen3(*cmd) {|stdin, stdout, stderr, wait_thr| ... } -> ()

外部プログラム cmd を実行し、そのプロセスの標準入力、標準出力、標準エラー出力に接続されたパイプと実行したプロセスを待つためのスレッドを 4 要素の配列で返します。

require 'open3'
stdin, stdout, stderr, wait_thr = *Open3.popen3("/usr/bin/nroff -man")
[PARAM] cmd:
実行するコマンドを指定します。
[RETURN]
ブロックを指定した場合はブロックの最後に評価された値を返します。ブロックを指定しなかった場合は標準入力、標準出力、標準エラー出力と実行したプロセスを待つためのスレッドに接続されたパイプを返します。

ブロックを指定するとパイプの配列を引数にブロックを実行し、最後にパイプを close します。この場合はブロックの最後の式の結果を返します。

require 'open3'

Open3.popen3("read stdin; echo stdout; echo stderr >&2") {|stdin, stdout, stderr, wait_thr|
  stdin.puts "stdin"
  stdin.close     # または close_write
  p stdout.read
  p stderr.read
}
#=> "stdout\n"
    "stderr\n"

stdin への入力が終わったらできる限り早く close か close_write で閉じるべきです。

[UNIX系OS固有の注意] Open3 で作成した子プロセスは wait(2) しなくてもゾンビになりません。

引数 cmd はそのまま Kernel.#spawn に渡されます。 Kernel.#spawnと同様に、引数リストの最初に環境変数をハッシュ形式で指定する事ができます。

例:

require 'open3'

Open3.popen3({"foo" => "1", "bar" => "2"}, "env") {|i, o, e, t|
  i.close
  print o.read
}
#=> ...
    foo=1
    bar=2

Kernel.#spawnと同様に、引数リストの最後にオプションをハッシュ形式で指定する事ができます。

例:

require "open3"

# オプションを指定した場合。
Dir.chdir("/tmp")
Open3.popen3("pwd", :chdir=> "/") {|i,o,e,t|
  p o.read.chomp #=> "/"
}

# オプションを指定しない場合。
Dir.chdir("/tmp")
Open3.popen3("pwd") {|i,o,e,t|
  p o.read.chomp #=> "/tmp"
}

[SEE_ALSO] Kernel.#spawn