Skip to content

Instantly share code, notes, and snippets.

@whitehat101
Last active May 14, 2016 07:09
Show Gist options
  • Save whitehat101/c818bd19f0554f53658d7fb1aa1a74f8 to your computer and use it in GitHub Desktop.
Save whitehat101/c818bd19f0554f53658d7fb1aa1a74f8 to your computer and use it in GitHub Desktop.
RealStdOut = $stdout
# Replace the main thread's $stdout and $stderr with IO.pipes
# Create a thread to watch for data on the pipes
# call given block with IO name, timestamp, and data read from IO
def redirect_stdout_and_stderr_to &callback
rout, $stdout = IO.pipe
rerr, $stderr = IO.pipe
map = { rout => 'stdout', rerr => 'stderr' }
Thread.new do
buffer = ''
ios = [ rout, rerr ]
until ios.empty? do
read, write = IO.select ios, []
stamp = Time.now.to_f
read.each do |io|
begin
io.readpartial 2048, buffer
callback[map[io], stamp, buffer]
rescue EOFError => e
ios.delete io
callback[map[io], stamp, "EOFError: #{e}"]
end
end
end
end
end
t = redirect_stdout_and_stderr_to do |name,stamp,message|
RealStdOut.puts "#{name}-#{stamp}: #{message.inspect}"
end
puts :hi # stdout-XXX2742887.3437052: "hi\n"
print :hi # stdout-XXX2742888.5288196: "hi"
t.status # => "sleep"
$stderr.close # stderr-XXX2742889.2119832: "EOFError: end of file reached"
t.status # => "sleep"
$stdout.close # stdout-XXX2742890.3000205: "EOFError: end of file reached"
t.status # => false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment