My favorite way to work with shell commands is like so:
Open3.popen3 "shellcommand --args --more-args" do |stdin, stdout, stderr, thread|
while line = stdout.gets
puts line
end
end
The command gives you input, output and error streams. You can call stdout.gets to get the next line of output (my favorite), or stdout.getc for the next character, if you really want immediacy. The function waits until input is available and then returns nil when the command completes, so a common technique is to wrap the command in a while-loop and have a set of commands repeatedly execute until the command completes.