如何使用Ruby和IO.popen写和读进程?

z9zf31ra  于 12个月前  发布在  Ruby
关注(0)|答案(2)|浏览(119)

我写了这个,但是没有用...

output = IO.popen("irb", "r+") do |pipe|
  pipe.gets
  pipe.puts "10**6"
  pipe.gets
  pipe.puts "quit"
end

我这样改写

IO.popen("irb", "w+") do |pipe|
  3.times {puts pipe.gets} # startup noise
  pipe.puts "10**6\n"
  puts pipe.gets # I expect " => 1000000"
  pipe.puts "quit" # I expect exit from irb
end

但它也没有工作

7kqas0il

7kqas0il1#

一般来说,上面的例子会挂起,因为管道仍然打开写,你调用的命令(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 3.1 popen*

更多详情:

在Ruby中,IO.popenIO.popen2IO.popen2eIO.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
r6hnlfcb

r6hnlfcb2#

要么

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

相关问题