Bash - 如何从后台 ruby 脚本获取 STDOUT
Bash - How to get STDOUT from a background ruby script
我需要 运行 一个 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
不是普通安装的 ruby 解释器;这是一个 运行s ruby
在 Docker 容器中的脚本。所以这可能是一个 Docker 问题。我在一台安装了普通 ruby 解释器的机器上进行了测试,它运行良好。接下来我将调查 Docker 缓冲问题。
我找到了问题和解决方案。
问题:
- 为什么我能看到
ping
的输出而不是 loop.rb
的输出?
因为我的本地 ruby
不是真正的 ruby 解释器,而是在 docker 容器内运行 ruby
的脚本(比使用 [=更易于管理 rvm
恕我直言)。所以这是一个 docker 管道缓冲区问题。
解决方法:
- 如何在 Bash 的后台获取
loop.rb
的输出?
通过使用 unbuffer
command:
sony@sonymint:~/test$ unbuffer ./loop.rb &
[3] 7262
sony@sonymint:~/test$ loop!
loop!
loop!
loop!
尝试将其放在脚本的开头:
STDOUT.sync = true
这应该在 Ruby 脚本的标准输出上禁用缓冲。如果系统的 libc 检测到它没有在交互式 shell.
中被 运行,则该缓冲通常由系统的 libc 完成。
我需要 运行 一个 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
不是普通安装的 ruby 解释器;这是一个 运行s ruby
在 Docker 容器中的脚本。所以这可能是一个 Docker 问题。我在一台安装了普通 ruby 解释器的机器上进行了测试,它运行良好。接下来我将调查 Docker 缓冲问题。
我找到了问题和解决方案。
问题:
- 为什么我能看到
ping
的输出而不是loop.rb
的输出?
因为我的本地 ruby
不是真正的 ruby 解释器,而是在 docker 容器内运行 ruby
的脚本(比使用 [=更易于管理 rvm
恕我直言)。所以这是一个 docker 管道缓冲区问题。
解决方法:
- 如何在 Bash 的后台获取
loop.rb
的输出?
通过使用 unbuffer
command:
sony@sonymint:~/test$ unbuffer ./loop.rb &
[3] 7262
sony@sonymint:~/test$ loop!
loop!
loop!
loop!
尝试将其放在脚本的开头:
STDOUT.sync = true
这应该在 Ruby 脚本的标准输出上禁用缓冲。如果系统的 libc 检测到它没有在交互式 shell.
中被 运行,则该缓冲通常由系统的 libc 完成。