Bash - 如何从后台ruby脚本获取STDOUT

时间:2016-10-24 14:28:02

标签: ruby bash background-process

我需要在后台运行一个ruby脚本,但我希望实时看到它的输出。

我写了一个名为loop.rb的简单测试:

#!/usr/bin/env ruby

(1..4).each do
  puts "loop!"
  sleep 1
end

前景输出是:

sony@sonymint:~/test$ ./loop.rb
loop!
loop!
loop!
loop!

但我无法在后台看到它:

sony@sonymint:~/test$ ./loop.rb &
[2] 3935
sony@sonymint:~/test$ 

但是我可以在后台看到ping的输出:

sony@sonymint:~/test$ ping google.com &
[2] 3734                                                                                                                                                                                                                                                                     
sony@sonymint:~/test$ PING google.com (64.233.190.113) 56(84) bytes of data.                                                                                                                                                                                                 
64 bytes from ce-in-f113.1e100.net (64.233.190.113): icmp_seq=1 ttl=42 time=79.6 ms                                                                                                                                                                                          
64 bytes from ce-in-f113.1e100.net (64.233.190.113): icmp_seq=2 ttl=42 time=79.5 ms                                                                                                                                                                                          
64 bytes from ce-in-f113.1e100.net (64.233.190.113): icmp_seq=3 ttl=42 time=81.7 ms                                                                            

所以,有两个问题:

  1. 为什么我可以看到ping的输出而不是loop.rb的输出?

  2. 如何在Bash的后台获取loop.rb的输出?

  3. 更新

    评论中的@TomLord是对的:有一些奇怪的系统配置。我的ruby本地不是一个普通安装的红宝石翻译;它是一个在Docker容器中运行ruby的脚本。所以它可能是一个Docker问题。我在一台装有普通安装的ruby解释器的机器上测试过,它工作正常。我接下来将研究Docker缓冲问题。

2 个答案:

答案 0 :(得分:2)

我发现了问题和解决方案。

问题:

  1. 为什么我可以看到ping的输出而不是loop.rb的输出?
  2. 因为我的本地ruby不是真正的ruby解释器,但它是一个在docker容器中运行ruby的脚本(比使用rvm恕我直言更容易管理)。所以它是一个docker管道缓冲区问题。

    解决方案:

    1. 如何在Bash的后台获取loop.rb的输出?
    2. 使用unbuffer command

      sony@sonymint:~/test$ unbuffer ./loop.rb & 
      [3] 7262
      sony@sonymint:~/test$ loop! 
      loop! 
      loop! 
      loop! 
      

答案 1 :(得分:2)

尝试将其放在脚本的开头:

STDOUT.sync = true

这应该禁用Ruby脚本的标准输出上的缓冲。缓冲通常由系统的libc完成,如果它检测到它没有在交互式shell中运行。