Skip to content

Instantly share code, notes, and snippets.

@mitio
Last active January 21, 2017 18:01
Show Gist options
  • Save mitio/8ac70012b2c489a482fff991ca8dfcea to your computer and use it in GitHub Desktop.
Save mitio/8ac70012b2c489a482fff991ca8dfcea to your computer and use it in GitHub Desktop.
require 'open3'
class Command
def run(command, stdout_callback, stderr_callback)
Open3.popen3(command) do |stdin_write_io, stdout_read_io, stderr_read_io, process_wait_thread|
# We don't care about STDIN
stdin_write_io.close
stdout_reader = read_without_blocking_from(stdout_read_io, stdout_callback)
stderr_reader = read_without_blocking_from(stderr_read_io, stderr_callback)
exit_status = process_wait_thread.value
stdout_reader.join
stderr_reader.join
exit_status # A Process::Status instance
end
end
private
def read_without_blocking_from(io, data_available_callback)
Thread.new do
begin
data_available_callback.(io.read_nonblock(4096)) until io.closed?
rescue IO::WaitReadable
IO.select([io])
retry
rescue EOFError
# Ignore end of file reached (EOFError)
end
end
end
end
Command.new.run('echo 1; sleep 1; echo 2; foobar; sleep 1; echo 3', -> x { puts "STDOUT: #{x}" }, -> x { puts "STDERR: #{x}" })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment