def execute(command, options = {})
redacted = options[:redacted] || []
redacted_command = command
redacted.each { |word| redacted_command = redacted_command.gsub(word, '<REDACTED>') }
@log.debug "Executing command: '#{redacted_command}'"
output = ""
STDOUT.sync = true
STDERR.sync = true
begin
pid, stdin, stdout, stderr = (RUBY_PLATFORM =~ %rjava/ ? IO : Open4).send(:popen4, command)
threads = []
threads << Thread.new(stdout) do |out|
out.each do |l|
l.chomp!
l.strip!
output << "\n#{l}"
@log.debug l
end
end
threads << Thread.new(stderr) do |err|
err.each do |l|
l.chomp!
l.strip!
output << "\n#{l}"
@log.debug l
end
end
threads.each { |t| t.join }
status = AStruct.new(:exitstatus => 0)
fakepid, status = Process.waitpid2(pid) if process_alive?(pid)
raise "process exited with wrong exit status: #{status.exitstatus}" if !(RUBY_PLATFORM =~ %rjava/) and status.exitstatus != 0
return output.strip
rescue Interrupt
raise InterruptionError.new(pid), "Program was interrupted."
rescue => e
@log.error e.backtrace.join($/)
raise "An error occurred while executing command: '#{redacted_command}', #{e.message}"
end
end