从Ruby运行交互式程序

从Ruby运行交互式程序,ruby,stdout,popen,interactive,Ruby,Stdout,Popen,Interactive,我试图从ruby运行gnuplot(不使用外部gem)并解析其文本输出。我尝试了IO.popen、PTY.spawn和Open3.popen3,但每当我尝试获取输出时,它都会“挂起”——我猜是在等待更多的输出。我觉得它是用Thread.new完成的,但是我找不到正确的方法来实现它 有人知道它是如何完成的吗?问题是子程序正在等待未发送的输入 通常,当我们调用一个需要输入STDIN的程序时,我们必须关闭STDIN,然后STDIN发出信号让该程序开始处理。查看各种方法,您将看到许多示例中出现了stdi

我试图从ruby运行gnuplot(不使用外部gem)并解析其文本输出。我尝试了
IO.popen
PTY.spawn
Open3.popen3
,但每当我尝试获取输出时,它都会“挂起”——我猜是在等待更多的输出。我觉得它是用
Thread.new
完成的,但是我找不到正确的方法来实现它


有人知道它是如何完成的吗?

问题是子程序正在等待未发送的输入

通常,当我们调用一个需要输入STDIN的程序时,我们必须关闭STDIN,然后STDIN发出信号让该程序开始处理。查看各种方法,您将看到许多示例中出现了
stdin.close
,但它们没有解释原因

Open3还包括and,这使它在处理一个需要STDIN而您没有任何东西要发送给它的程序时变得很好。在这两种方法中,STDIN立即关闭,并且该方法返回被调用程序的STDOUT、STDERR和exit状态


您需要“期望”功能。Ruby的类包含一个方法

创建和管理伪终端(PTY)。另请参见en.wikipedia.org/wiki/Pseudo_terminal

虽然它没有很好的文档记录,也没有提供我所看到的很多功能。有关其使用示例,请访问“”


相反,您可能想看看哪一个文档记录得更好,并且看起来是最新的。

我想这就是您想要的:

require 'pty'
require 'expect'

PTY.spawn('gnuplot') do |input, output, pid|
  str = input.expect(/gnuplot>/)
  puts str
  output.puts "mlqksdf"

  str = input.expect(/gnuplot>/)
  puts str
  output.puts "exit"
end

如果这是标准输出,请尝试通过shell命令获取它。请将您的命令用反勾(
`command`
)括起来,或者使用
%x(command)
我正在尝试运行一个交互式程序。不知怎的,我错过了标题。很抱歉你用Open3到底试过什么?
i,o,e,th=Open3.popen3('gnuplot');请把你的名字写下来!o、 eof请参阅“”,这很可能是此问题的答案。我不希望从输出中匹配模式,我希望在不阻止输入的情况下完全获得模式。抱歉。这里有一个更好的解决方案,当我通过stdin发送命令并关闭它时,我可以读取stdout和stderr。但是我如何重新打开stdin来发送另一个命令呢?你没有。这就是为什么你需要“expect”,它会观察交互响应,然后发送下一个输入。好吧,显然我错了。至少,正如托马斯所建议的那样,我可以期待出现“gnuplot>”行。非常感谢。