【问题标题】:ruby popen3 -- how to repeatedly write to stdin & read stdout without re-opening process?ruby popen3 - 如何在不重新打开进程的情况下重复写入标准输入和读取标准输出?
【发布时间】:2014-04-04 01:01:39
【问题描述】:

我正在使用Open3popen3 方法启动一个进程,该进程以类似控制台/REPL 的方式运行,以重复接受输入并返回输出。

我可以正常打开进程、发送输入和接收输出,代码如下:

Open3.popen3("console_REPL_process") do |stdin, stdout, stderr, wait_thr|
    stdin.puts "a string of input"
    stdin.close_write
    stdout.each_line { |line| puts line } #successfully prints all the output
end

我想连续多次执行此操作,而无需重新打开进程,因为启动需要很长时间。

我知道我必须关闭标准输入才能返回标准输出。但我不知道的是,我如何“重新打开”标准输入以便我可以写更多输入?

理想情况下,我想做这样的事情:

Open3.popen3("console_REPL_process") do |stdin, stdout, stderr, wait_thr|
    stdin.puts "a string of input"
    stdin.close_write
    stdout.each_line { |line| puts line }

    stdin.reopen_somehow()

    stdin.puts "another string of input"
    stdin.close_write
    stdout.each_line { |line| puts line }
    # etc..
end

解决方案

感谢 pmoo 的回答,我能够使用 PTYexpect 设计一个解决方案,期望进程在准备好接受更多输入时返回提示字符串,如下所示:

PTY.spawn("console_REPL_process") do |output, input|
    output.expect("prompt >") do |result|
      input.puts "string of input"
    end
    output.expect("prompt >") do |result|
      puts result
      input.puts "another string of input"
    end
    output.expect("prompt >") do |result|
      puts result
      input.puts "a third string of input"
    end
    # and so forth
end

【问题讨论】:

    标签: ruby popen3


    【解决方案1】:

    您可以使用expect 库取得一些成功,并让子进程显式标记每个输出的结束,例如:

    require 'expect'
    require 'open3'
    
    Open3.popen3("/bin/bash") do
        | input, output, error, wait_thr |
        input.sync = true
        output.sync = true
    
        input.puts "ls /tmp"
        input.puts "echo '----'"
        puts output.expect("----", 5)
    
        input.puts "cal apr 2014"
        input.puts "echo '----'"
        puts output.expect("----", 5)
    end
    

    作为奖励,expect 有一个 timeout 选项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-25
      • 2019-09-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-25
      相关资源
      最近更新 更多