Class: Giddyup::CommandWrapper
- Inherits:
-
Object
- Object
- Giddyup::CommandWrapper
- Defined in:
- lib/giddyup/command_wrapper.rb
Defined Under Namespace
Classes: CommandFailed
Class Method Summary collapse
-
.run_command(cmd) ⇒ Object
Run a command and return the output of the command as an array containing elements of the following form:.
-
.run_command_stdout(cmd) ⇒ Object
Run a command, but only return stdout as a string.
Class Method Details
.run_command(cmd) ⇒ Object
Run a command and return the output of the command as an array containing elements of the following form:
- <stream>, <line>
-
Where <stream> is either :stdout or :stderr (to indicate which output stream the line came from), and <line> is the line of text (sans trailing newline) that was output.
These lines of text are interspersed in the order they were received, to ensure the best possible match-up of errors to regular output.
If the command returns a non-zero exit code, a Giddyup::CommandWrapper::CommandFailed exception is raised containing the status of the failed command and all output.
If a block is passed, it will be called for each line of output, and pass two arguments: ‘<stream>` and `<line>`.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/giddyup/command_wrapper.rb', line 42 def self.run_command(cmd) output = [] rv = nil Open3.popen3(cmd) do |stdin, stdout, stderr, thr| # We don't want to talk *to* you stdin.close fds = [stdout, stderr] until fds.empty? a = IO.select(fds, [], [], 0.1) if a.nil? if fds == [stderr] # SSH is an annoying sack of crap. When using ControlMaster # (multiplexing), the background mux process keeps stderr open, # which means that this loop never ends (because stderr.eof? # is never true). So, we're using the heuristic that if stdout # is closed (ie it hsa been removed from `fds`) and we've timed # out rather than seeing any further activity on stderr) then # the command execution is done. break else # We had a timeout, but we're still running! next end end if a[0].include? stdout if stdout.eof? stdout.close fds.delete(stdout) else l = stdout.readline.chomp yield :stdout, l if block_given? output << [:stdout, l] end end if a[0].include? stderr if stderr.eof? stderr.close fds.delete(stderr) else l = stderr.readline.chomp yield :stderr, l if block_given? output << [:stderr, l] end end end rv = thr.value end if rv.exitstatus != 0 raise CommandFailed.new(rv, output, cmd) end output end |
.run_command_stdout(cmd) ⇒ Object
Run a command, but only return stdout as a string
105 106 107 108 109 110 |
# File 'lib/giddyup/command_wrapper.rb', line 105 def self.run_command_stdout(cmd) run_command(cmd). select { |l| l[0] == :stdout }. map { |l| l[1] }. join("\n") end |