Skip to content

Instantly share code, notes, and snippets.

@troelskn
Created October 24, 2018 14:11
Show Gist options
  • Save troelskn/8f5f887e144c5ca6631ede8dc6fe6249 to your computer and use it in GitHub Desktop.
Save troelskn/8f5f887e144c5ca6631ede8dc6fe6249 to your computer and use it in GitHub Desktop.
Running a shell subprocess is surprisingly hard in ruby
require "open3"
def execute_shell(command, verbose: false)
Rails.logger.info "[SHELL] #{command}"
# see: https://nickcharlton.net/posts/ruby-subprocesses-with-stdout-stderr-streams.html
# see: http://stackoverflow.com/a/1162850/83386
output = []
Open3.popen3(command) do |stdin, stdout, stderr, thread|
# read each stream from a new thread
readers = { :out => stdout, :err => stderr }.map do |key, stream|
Thread.new do
until (raw_line = stream.gets).nil? do
line = raw_line.strip
next if line.empty?
case key
when :out
Rails.logger.debug "[STDOUT] #{line}" if verbose
output << line
when :err
Rails.logger.warn "[STDERR] #{line}"
end
end
end
end
thread.join # don't exit until the external process is done
readers.map(&:join) # give reader threads a chance to clear out open buffers
end
output
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment