7

If I do this:

output = %x{some_script}

...then I have the stuff printed to stdout stored in output; but I don't see it appear on the screen.

On the other hand, if I do this:

success = system "some_script"

...then I see the output appear on the screen, but I don't have it stored in a variable (success just holds a boolean value).

Is there some way to get both? I'm aware I could do this:

output = %x{some_script}
puts output

But the problem there is that some_script might be a pretty long-running script, in which case I see nothing until the whole thing is finished. I'd prefer to see output as it's produced, and when it's finished to have it all stored in the output variable.

2 Answers 2

9

This is a solution with IO.popen:

require 'stringio'

output = StringIO.new

IO.popen("ls") do |pipe|
  pipe.each do |line|
    output.puts line
    puts line
  end
end

puts output.string # => Outputs the contents of `output` as a string
Sign up to request clarification or add additional context in comments.

4 Comments

Or use popen3 if the standard error stream is also desired.
Am I missing something? This also appears to wait until the command has finished executing, much like the %x{} + puts option.
@Dan: Sounds like you have a buffering problem.
My mistake: I used an overly simplistic script to test this on; after taking the hint from @mu and actually trying it on my real script, I see that it works. Thanks!
1

You could monkeypatch Kernel::puts, but I can only think of a kludgy global way to store the results:

class Kernel
  alias_method :old_puts, :puts
  def puts(*args)
    old_puts args
    $output << args
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.