如何在 Ruby 中修复挂起的 popen3? [英] How to fix hanging popen3 in Ruby?

查看:21
本文介绍了如何在 Ruby 中修复挂起的 popen3?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 popen3 时遇到了意外行为,我想用它来运行像工具 ala cmd < 这样的命令.文件 1 >文件 2.下面的示例挂起,因此永远不会到达 stdout done.使用除 cat 之外的其他工具可能会导致挂起,因此永远不会到达 stdin done.我怀疑,我正在遭受缓冲,但我该如何解决这个问题?

I am getting unexpected behaviour using popen3, which I want to use to run a command like tool ala cmd < file1 > file2. The below example hangs, so that stdout done is never reached. Using other tools than cat may cause hanging, so that stdin done is never reached. I suspect, I am suffering from buffering, but how do I fix this?

#!/usr/bin/env ruby

require 'open3'

Open3.popen3("cat") do |stdin, stdout, stderr, wait_thr|
  stdin.puts "foobar"

  puts "stdin done"

  stdout.each_line { |line| puts line }

  puts "stdout done"

  puts wait_thr.value
end

puts "all done"

推荐答案

stdout.each_line 正在等待 cat 的进一步输出,因为 cat的输出流仍然打开.它仍然是打开的,因为 cat 仍在等待用户的输入,因为它的输入流还没有关闭(你会注意到,当你在终端中打开 cat并输入 foobar,它仍会运行并等待输入,直到您按 ^d 关闭流).

stdout.each_line is waiting for further output from cat because cat's output stream is still open. It's still open because cat is still waiting for input from the user because its input stream hasn't been closed yet (you'll notice that when you open cat in a terminal and type in foobar, it will still be running and waiting for input until you press ^d to close the stream).

所以要解决这个问题,只需在打印输出之前调用 stdin.close.

So to fix this, simply call stdin.close before you print the output.

这篇关于如何在 Ruby 中修复挂起的 popen3?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆