-
-
Save scratchoo/e7831d58a6a08096b49a150bcfc7035d to your computer and use it in GitHub Desktop.
Running a shell subprocess is surprisingly hard in ruby
This file contains 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 "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