我写了这个,但没有用...
output = IO.popen("irb", "r+") do |pipe| 管道获取 管道.puts“10**6” 管道获取 pipeline.puts“退出” 结尾
我这样重写
IO.popen("irb", "w+") 做 |pipe| 3.times {puts pipeline.gets} # 启动噪音 管道.puts“10**6 ” puts pipeline.gets # 我期望“ => 1000000” pipeline.puts "quit" # 我希望从 irb 退出 结尾但它也不起作用
一般来说,上面的示例将挂起,因为管道仍然打开用于写入,并且您调用的命令(Ruby 解释器)需要更多命令/数据。
另一个答案将
__END__
发送到 ruby——这在这里有效,但是这个技巧当然不适用于您可能通过 popen
调用的任何其他程序。
使用
popen
时,需要用IO#close_write
关闭管道。
IO.popen("ruby", "r+") do |pipe|
pipe.puts "puts 10**6"
pipe.close_write # make sure to close stdin for the program you call
pipe.gets
end
更详细:
在 Ruby 中,
IO.popen
、IO.popen2
、IO.popen2e
和 IO.popen3
是用于处理子进程的方法,它们的不同之处在于处理输入、输出和错误流的方式。以下是对差异以及何时使用它们的解释:
IO.popen
:
IO.popen
是一种多功能方法,允许您创建子流程并与其标准输入和输出交互。stdin, stdout, thr = IO.popen('some_command')
IO.popen2
:
IO.popen2
创建一个具有单独管道的子进程,用于标准输入和输出。stdin, stdout = IO.popen2('some_command')
IO.popen2e
:
IO.popen2e
与 IO.popen2
类似,但它将标准输出和标准错误流合并到单个流中。stdin, stdout_err = IO.popen2e('some_command')
IO.popen3
:
IO.popen3
创建一个子进程,其中包含用于标准输入、标准输出和标准错误的单独管道。stdin, stdout, stderr, thr = IO.popen3('some_command')
何时使用每个版本取决于您的具体要求:
当您需要与子流程的输入和输出交互并且不需要单独处理错误消息时,请使用
IO.popen
。
当您想要与标准输入分开捕获标准输出并需要将数据发送到进程时,请使用
IO.popen2
。
当您想要在单个流中同时捕获标准输出和标准错误时,请使用
IO.popen2e
。
当您需要单独的管道用于标准输入、标准输出和标准错误,并且希望与子进程交互并分别捕获输出和错误消息时,请使用
IO.popen3
。
要么做
IO.popen("ruby", "r+") do |pipe|
pipe.puts "puts 10**6"
pipe.puts "__END__"
pipe.gets
end
或者做
IO.popen("irb", "r+") do |pipe|
pipe.puts "\n"
3.times {pipe.gets} # startup noise
pipe.puts "puts 10**6\n"
pipe.gets # prompt
pipe.gets
end