lib/ztk/command.rb in ztk-0.2.0 vs lib/ztk/command.rb in ztk-0.2.1

- old
+ new

@@ -43,10 +43,15 @@ def initialize(config={}) super(config) end + def inspect + @hostname ||= %x(hostname -f).chomp + "#{ENV['USER']}@#{@hostname}" + end + # Executes a local command. # # @param [String] command The command to execute. # @param [Hash] options The options hash for executing the command. # @@ -58,14 +63,17 @@ # # cmd = ZTK::Command.new # puts cmd.exec("hostname -f").inspect def exec(command, options={}) options = OpenStruct.new({ :exit_code => 0, :silence => false }.merge(options)) - log(:debug) { "config(#{@config.inspect})" } log(:debug) { "options(#{options.inspect})" } log(:debug) { "command(#{command.inspect})" } + output = "" + stdout_header = false + stderr_header = false + parent_stdout_reader, child_stdout_writer = IO.pipe parent_stderr_reader, child_stderr_writer = IO.pipe pid = Process.fork do parent_stdout_reader.close @@ -81,17 +89,46 @@ Kernel.exec(command) end child_stdout_writer.close child_stderr_writer.close - Process.waitpid(pid) + reader_writer_key = {parent_stdout_reader => :stdout, parent_stderr_reader => :stderr} + reader_writer_map = {parent_stdout_reader => @config.stdout, parent_stderr_reader => @config.stderr} - stdout = parent_stdout_reader.read - stderr = parent_stderr_reader.read - output = (stdout || '') + (stderr || '') + direct_log(:debug) { "===[STARTED]===[STARTED]===[#{self.inspect}]===[STARTED]===[STARTED]===\n" } + loop do + break if reader_writer_map.keys.all?{ |reader| reader.eof? } - @config.stdout.write(stdout) unless options.silence - @config.stderr.write(stderr) unless options.silence + sockets = IO.select(reader_writer_map.keys).first + sockets.each do |socket| + data = socket.read + next if (data.nil? || data.empty?) + + case reader_writer_key[socket] + when :stdout then + if !stdout_header + direct_log(:debug) { "===[STDOUT]===[STDOUT]===[#{self.inspect}]===[STDOUT]===[STDOUT]===\n" } + stdout_header = true + stderr_header = false + end + reader_writer_map[socket].write(data) unless options.silence + + when :stderr then + if !stderr_header + direct_log(:debug) { "===[STDERR]===[STDERR]===[#{self.inspect}]===[STDERR]===[STDERR]===\n" } + stderr_header = true + stdout_header = false + end + reader_writer_map[socket].write(data) unless options.silence + end + + direct_log(:debug) { data } + output += data + end + end + direct_log(:debug) { "===[FINISHED]===[FINISHED]===[#{self.inspect}]===[FINISHED]===[FINISHED]===\n" } + + Process.waitpid(pid) parent_stdout_reader.close parent_stderr_reader.close log(:debug) { "exit_code(#{$?.inspect})" }