我正在使用Open3的popen3方法启动一个进程,该进程以类似控制台的/ 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,以便我可以写更多的输入?
理想情况下,我想做这样的事情:
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的回答,我设计了一个使用PTY和expect的解决方案,期望进程在准备好更多输入时返回提示符字符串,如下所示:
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发布于 2014-04-05 01:34:28
您可以使用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选项。
https://stackoverflow.com/questions/22851698
复制相似问题