我需要在后台运行一个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
所以,有两个问题:
为什么我可以看到ping
的输出而不是loop.rb
的输出?
如何在Bash的后台获取loop.rb
的输出?
更新
评论中的@TomLord是对的:有一些奇怪的系统配置。我的ruby
本地不是一个普通安装的红宝石翻译;它是一个在Docker容器中运行ruby
的脚本。所以它可能是一个Docker问题。我在一台装有普通安装的ruby解释器的机器上测试过,它工作正常。我接下来将研究Docker缓冲问题。
答案 0 :(得分:2)
我发现了问题和解决方案。
问题:
ping
的输出而不是loop.rb
的输出?因为我的本地ruby
不是真正的ruby解释器,但它是一个在docker容器中运行ruby
的脚本(比使用rvm
恕我直言更容易管理)。所以它是一个docker管道缓冲区问题。
解决方案:
loop.rb
的输出?sony@sonymint:~/test$ unbuffer ./loop.rb &
[3] 7262
sony@sonymint:~/test$ loop!
loop!
loop!
loop!
答案 1 :(得分:2)
尝试将其放在脚本的开头:
STDOUT.sync = true
这应该禁用Ruby脚本的标准输出上的缓冲。缓冲通常由系统的libc完成,如果它检测到它没有在交互式shell中运行。