エスケープよりexec
HTML の実体参照化もしたほうがいいんじゃないかとそういう話もあるけれど。
そもそも、単純に IO.popen に渡すコマンドをエスケープしないといけないというのがいけてない。ポータビリティとか考え出すと恐ろしいし。
ということで、Open3.popen3 を使うか、IO.popen で "-" を指定して fork/exec するとかしたほうが良いんじゃなかろうか。こういうのね。
def popen(cmd, args, mode, &block) IO.popen('-', mode) do |io| if io # parent block.call(io) else # child exec(cmd, *args) end end end popen('ls', ARGV, 'r') do |p| p.each do |line| puts line end end
Open3 を使う場合はこうか。
require 'open3' Open3.popen3('ls', *ARGV) do |stdin, stdout, stderr| stdout.each do |line| puts line end end