nicoolas25
7/31/2014 - 8:01 AM

Follow line by line the output of a subprocess.

Follow line by line the output of a subprocess.

require 'timeout'

cmd = [
  'sleep 3 ; echo "toto" ; sleep 3 ; echo "toto"',
  'find /*',
  'find /tmp'
]

begin
  output, input = IO.pipe
  pid = spawn(cmd[2], out: input)
  loop do
    # Do not wait more than 2 seconds for an input, the process could be exited
    Timeout::timeout(2) do
      # Read one line at a time continuously
      loop do
        chunck = output.readline
        puts "Line received: #{chunck}"
      end
    end rescue nil
  
    # Check if the process is still alive
    break if Process.waitpid(pid, Process::WNOHANG)
  end
  
  # Read the rest of the output (just in case)
  # You should also choose a better suited number than 100000 depending on your command
  remaining_chunck = output.read_nonblock(100000) rescue nil
  puts "Remaining lines: #{remaining_chunck}" if remaining_chunck
  
  # Display a nice message to the user
  exit_status = $?
  puts "The command and was #{exit_status.success? ? '' : 'not '}a success"
end