Search code examples
rubybashbackground-process

Bash - How to get STDOUT from a background ruby script


I need to run one ruby script in background, but I want to see its output in real time.

I wrote a simple test called loop.rb:

#!/usr/bin/env ruby

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

Whose foreground output is:

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

But I can't see it in background:

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

However I can see the ping's output in background:

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                                                                            

So, two questions:

  1. Why can I see the output of ping and not the output of loop.rb?

  2. How to get the output of loop.rb in background in Bash?

UPDATE

@TomLord in comment is right: there is some odd system configuration. Locally my ruby is not a plain-installed ruby interpreter; it's a script which runs ruby inside a Docker container. So it can be a Docker issue. I tested on a machine with a plain-installed ruby interpreter and it worked fine. I'll investigate Docker buffering issues next.


Solution

  • I've found the problem and the solution.

    The problem:

    1. Why can I see the output of ping and not the output of loop.rb?

    Because my local ruby is not a genuine ruby interpreter, but it's a script which runs ruby inside a docker container (easier to manage than using rvm IMHO). So it's a docker pipe buffer issue.

    The solution:

    1. How to get the output of loop.rb in background in Bash?

    By using the unbuffer command:

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