微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby popen3 – 如何反复写入stdin并读取stdout而无需重新打开过程?

我正在使用 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

我想连续多次这样做,而不需要重新打开过程,因为启动需要很长时间.

我知道我必须关闭stdin才能让stdout返回..但我不知道的是,我如何重新打开’stdin以便我可以写更多输入?

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

Open3.popen3("console_REPL_process") do |stdin,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的回答,我能够使用PTY设计一个解决方案并期望,只要它准备好接收更多输入,就会期望进程返回的提示字符串,如下所示:

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

解决方法

您可以使用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

作为奖励,期望有超时选项.

原文地址:https://www.jb51.cc/ruby/269762.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐