non vorrei lavorare

ブログ名の通りです。javascript three.js mruby rust OCaml golang julialang blender

mruby-ioでclose_writeを実装したが、不要だった件

こんばんは、週末は、土日とも近所の大きな公園に長男が自転車に自分の補助なしの自転車に乗って出かけてきたkjunichiです。

背景

echo "hoge"|cat

のようなことをmrubyでやりたかった。

mrubyで試すと動かない

IO#popenは"r+"指定で開くと、開いたパイプを読み書き出来ようだった。 そこで、以下のようなプログラムを作った。

IO.popen("cat","r+") do |pipe|
  pipe.puts "fugahoge"
  puts pipe.read
end

しかし、writeしてもcatから応答を読み込んでくれない。

write_closeを実装した

この状況を打破すべく、開いたパイプの書き込み側をクローズするclose_writeを実装した

IO.popen("cat","r+") do |pipe|
  pipe.puts "fugahoge"
  pipe.close_write
  puts pipe.read
end

これで、うまくcatの出力をmruby側で読み込むことができるようになった。

IO.pipeを使って解決できる!

先日、ffmpegの出力が標準出力でなく、 標準エラー出力にメッセージを吐いているの読み込みたく、mruby-ioのpopenのオプションを 調べている際にmruby-ioのテストコードから以下のように、IO#pipeで囲めば、標準入力と標準出力をブロック内で取得でき、IO#popenのブロックが終了後に取得しておいた標準出力を閉じることで、popenで開いたプロセスへのcloseを送れる。よって前述のclose_writeを使わずとも目的が達成できることを知った。

IO.pipe do |r,w|
  IO.popen("cat","w") do |pipe|
    pipe.puts "fugahoge"
  end
  w.close
  puts r.read
end

関連記事