Last active
August 29, 2015 14:16
-
-
Save cheeyeo/bdcb2f5d4201a53e2f7b to your computer and use it in GitHub Desktop.
Capture output from stdout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "tempfile" | |
# Captures the given stream and returns it: | |
# | |
# stream = capture(:stdout) { puts 'notice' } | |
# stream # => "notice\n" | |
# | |
# stream = capture(:stderr) { warn 'error' } | |
# stream # => "error\n" | |
# | |
# even for subprocesses: | |
# | |
# stream = capture(:stdout) { system('echo notice') } | |
# stream # => "notice\n" | |
# | |
# stream = capture(:stderr) { system('echo error 1>&2') } | |
# stream # => "error\n" | |
def capture(stream) | |
stream = stream.to_s | |
captured_stream = Tempfile.new(stream) | |
stream_io = eval("$#{stream}") | |
origin_stream = stream_io.dup | |
stream_io.reopen(captured_stream) | |
yield | |
stream_io.rewind | |
return captured_stream.read | |
ensure | |
captured_stream.unlink | |
stream_io.reopen(origin_stream) | |
end | |
output = capture(:stdout) do | |
puts "This goes to standard out" | |
STDOUT.puts "This tries to bypass capture" | |
system('echo "output from a subprocess"') | |
end | |
puts output.split('\n') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def capture_output | |
old_stdout, old_stderr = STDOUT.clone, STDERR.clone | |
pipe_r, pipe_w = IO.pipe | |
pipe_er, pipe_ew = IO.pipe | |
pipe_r.sync = true | |
pipe_er.sync = true | |
output = "" | |
err_output = "" | |
reader = Thread.new do | |
begin | |
loop do | |
output << pipe_r.readpartial(1024) | |
end | |
rescue EOFError | |
end | |
end | |
reader2 = Thread.new do | |
begin | |
loop do | |
err_output << pipe_er.readpartial(1024) | |
end | |
rescue EOFError | |
end | |
end | |
STDOUT.reopen(pipe_w) | |
STDERR.reopen(pipe_ew) | |
yield | |
ensure | |
STDOUT.reopen(old_stdout) | |
STDERR.reopen(old_stderr) | |
pipe_w.close | |
pipe_ew.close | |
reader.join | |
reader2.join | |
return "#{output} #{err_output}" | |
end | |
output = capture_output do | |
puts "This goes to standard out" | |
STDOUT.puts "This tries to bypass STDOUT" | |
system 'echo "output from a subprocess"' | |
STDERR.puts "This tries to bypass STDERR" | |
end | |
puts output.inspect |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment