Q:

How do I display the popen output as it happens through a get request?

I have some Ruby scripts that I use to automate some rsync tasks that can take a very long time to finish. I'm using popen to run a command:
def process(command)
  io = IO.popen(command) 
  output = io.read
  io.close 
  return output 
end

The command is executed by a get request in a Sinatra app:
get '/sync' do
  stream do |out|
    rsync_command = "rsync somedir" 
    out << process(rsync_command)
  end
end

Then I am accessing the output with an Ajax request on the front end:
$.get('/sync', function (data) {
 console.log(data);
});

Is it possible to display the shell output as it happens rather than only having it return at the end of the process?

A:

IO::popen:
Runs the specified command as a subprocess; the subprocess’s standard
  input and output will be connected to the returned IO object.

stdout is a file.  You are telling ruby to read the whole file with the line io.read, therefore ruby has to wait until the end of file is reached to return the text, which happens when the other end closes the pipe, i.e. when the target program has finished executing. You don't have to read a file a whole file at a time, instead you can read a file line by line:
def process(command)
  IO.popen(command) do |io|
    io.each do |line|
      puts line
    end
  end
end

That tells ruby to read the file until it finds a newline, then return the text...over and over gain until the end of file is reached.
Here's a full example:
#my_prog.rb

text = ""

1.upto(10) do
  text << "."

  puts text
  STDOUT.flush

  sleep 1
end

...
def process(command)
  IO.popen(command) do |io|
    io.each do |line|
      puts line
    end
  end
end

my_command = 'ruby ./my_prog.rb'
process(my_command)

Note that unless the target program flushes the output, the output will be buffered, and therefore the text won't be available to be read until the buffer is filled (at which point the buffer will be flushed automatically) or the target program ends(at which point the buffer also will be flushed automatically).  Instead of calling STDOUT.flush() repeatedly, you can just use the line STDOUT.sync = true at the top of your program.  When sync is set to true, ruby won't buffer the output.

