首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何修复Ruby中挂起的popen3?

如何修复Ruby中挂起的popen3?
EN

Stack Overflow用户
提问于 2012-01-21 17:46:03
回答 3查看 8.6K关注 0票数 15

我使用popen3得到了意想不到的行为,我想用它来运行像tool ala cmd < file1 > file2这样的命令。下面的示例挂起,因此永远无法访问stdout done。使用cat以外的其他工具可能会导致挂起,因此永远无法访问stdin done。我怀疑,我正在遭受缓冲的痛苦,但我如何解决这个问题?

代码语言:javascript
复制
#!/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"
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-21 17:51:15

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

因此,要解决这个问题,只需在打印输出之前调用stdin.close即可。

票数 15
EN

Stack Overflow用户

发布于 2013-05-15 23:00:21

您的代码挂起,因为 stdin 仍处于打开状态!

您需要使用IO#closeIO#close_write关闭它,如果您使用的是popen3

如果使用popen,则需要使用IO#close_write,因为它只使用一个文件描述符。

代码语言:javascript
复制
 #!/usr/bin/env ruby
 require 'open3'

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

   stdin.close   # close stdin like this!  or with stdin.close_write

   stdout.each_line { |line| puts line }

   puts wait_thr.value
 end

另请参阅:

Ruby 1.8.7 IO#close_write

Ruby 1.9.2 IO#close_write

Ruby 2.3.1 IO#close_write

票数 7
EN

Stack Overflow用户

发布于 2014-11-02 07:09:30

Tilo和sepp2k的答案是正确的:如果你关闭了stdin,你的简单测试就会结束。问题解决了。

尽管在你对answer of sepp2k的评论中,你表明你仍然经历着挂起。好吧,这里有一些你可能忽略的陷阱。

stderr已满缓冲区卡住

如果您调用的程序打印到stderr的数量超过了匿名管道的缓冲区所能容纳的数量(对于当前Linuxes为64KiB),则该程序将挂起。挂起的程序既不退出也不关闭stdout。因此,从其stdout读取将挂起。因此,如果你想做正确的事情,你必须使用线程或IO.select,非阻塞,无缓冲的读取,以便并行或轮流从标准输出和标准错误读取,而不会被卡住。

在标准输入的满缓冲区上卡住

如果您尝试向程序(cat)提供比"foobar“更多(更多)的内容,则标准输出的匿名管道的缓冲区将被填满。操作系统将挂起cat。如果您向stdin写入更多内容,则stdin的匿名管道的缓冲区将被填满。那么你打给stdin.write的电话就会卡住。这意味着:您需要并行或轮流写入stdin、从stdout读取和从stderr读取。

结论

阅读一本好书(Richards Stevens,"UNIX网络编程:进程间通信“),并使用好的库函数。IPC (进程间通信)太复杂了,容易出现不确定的运行时行为。这是太麻烦了,试图让它正确的尝试和错误。

使用Open3.capture3

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8952043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档