Ruby 2.2.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > IOクラス > popen
popen(env = {}, command, mode = "r", opt={}) -> IO[permalink][rdoc]popen(env = {}, command, mode = "r", opt={}) {|f| ... } -> objectpopen([env = {}, cmdname, *args, execopt={}], mode = "r", opt={}) -> IOpopen([env = {}, cmdname, *args, execopt={}], mode = "r", opt={}) {|f| ... } -> objectpopen([env = {}, [cmdname, arg0], *args, execopt={}], mode = "r", opt={}) -> IOpopen([env = {}, [cmdname, arg0], *args, execopt={}], mode = "r", opt={}) {|f| ... } -> objectpopen(env = {}, [cmdname, *args, execopt={}], mode = "r", opt={}) -> IOpopen(env = {}, [cmdname, *args, execopt={}], mode = "r", opt={}) {|f| ... } -> objectpopen(env = {}, [[cmdname, arg0], *args, execopt={}], mode = "r", opt={}) -> IOpopen(env = {}, [[cmdname, arg0], *args, execopt={}], mode = "r", opt={}) {|f| ... } -> objectサブプロセスを実行し、そのプロセスの標準入出力 との間にパイプラインを確立します。生成したパイプを IO オブジェクトとして返します。
p io = IO.popen("cat", "r+") # => #<IO:fd 4>
io.puts "foo"
io.close_write
p io.gets # => "foo\n"
サブプロセスを指定する方法は2通りあります。文字列を指定する場合と配列を指定する場合です。 文字列の場合は、シェルを経由して子プロセスを実行し、 配列の場合は、シェルを経由せずに子プロセスを実行します。
シェルを経由しない場合(上のシグネチャで cmdname を含む場合)には *args がサブプロセスの引数として使われます。この場合には *args はシェルでの ワイルドカード展開などはなされません。
配列内に配列を指定することで、arg0(みせかけのプログラム名)を指定することができます。
ブロックが与えられた場合は生成した IO オブジェクトを引数にブ ロックを実行し、ブロックの実行結果を返します。ブロックの実行後、生成したパイ プは自動的にクローズされます。
p IO.popen("cat", "r+") {|io|
io.puts "foo"
io.close_write
io.gets
}
# => "foo\n"
opt でプロセス起動のためのオプションや、パイプ IO オブジェクトの属性(エンコーディングや 読み書き能力)を指定することができます。 プロセス起動のためのオプションは Kernel.#spawn と、 パイプオブジェクトの属性の指定のオプションは IO.new と共通です。 つまり、 :external_encoding や :unsetenv_others が指定できます。 オプションの詳しい意味は Kernel.#spawn や IO.new を参照してください。
# nkfプロセスから得られる文字列を EUC-JP と指定する
# IO.new などと共通のオプションが指定できる
IO.popen("nkf -e filename", external_encoding: "EUC-JP"){|nkf_io|
nkf_io.read
}
これに加えて、プロセス起動のためのオプションを execopt で指定することもできます。 execopt ではエンコーディングなどは指定できません。
# 標準エラー出力を子プロセス側で標準出力にリダイレクトする
# 標準エラー出力と標準出力がマージされる
# Kernel.#spawn と共通のオプション
IO.popen(["ls", "/", :err=>[:child, :out]]) {|ls_io|
ls_result_with_error = ls_io.read
}
# 上と同じ、配列の外側でもオプションが指定できる
IO.popen(["ls", "/"], :err=>[:child, :out]) {|ls_io|
ls_result_with_error = ls_io.read
}
popen("-", mode = "r", opt={}) -> IO[permalink][rdoc]popen("-", mode = "r", opt={}) {|io| ... } -> objectpopen(env, "-", mode = "r", opt={}) -> IOpopen(env, "-", mode = "r", opt={}) {|io| ... } -> object第一引数に文字列 "-" が指定された時、fork(2) を 行い子プロセスの標準入出力との間にパイプラインを確立します。 親プロセスでは IO オブジェクトを返し、子プロセスでは nil を返します。
io = IO.popen("-", "r+")
if io # parent
io.puts "foo"
p io.gets # => "child output: foo\n"
io.close
else # child
s = gets
print "child output: " + s
exit
end
ブロックを与えられた場合、親プロセスでは生成した IO オブジェクトを引数に ブロックを実行し、その結果を返します。ブロックの実行後、生成したパイ プは自動的にクローズされます。 子プロセスでは nil を引数にブロックを実行し終了します。
p IO.popen("-", "r+") {|io|
if io # parent
io.puts "foo"
io.gets
else # child
s = gets
puts "child output: " + s
end
}
# => "child output: foo\n"
opt ではエンコーディングの設定やプロセス起動のためのオプションが指定できます。 IO.new や Kernel.#spawn で指定できるものと共通なので 詳しくはそちらを見てください。