Module: Libis::Tools::Command

Defined in:
lib/libis/tools/command.rb

Overview

This module allows to run an external command safely and returns it’s output, error messages and status. The run method takes any number of arguments that will be used as command-line arguments. The method returns a Hash with:

  • :out => an array with lines that were printed on the external program’s standard out.

  • :err => an array with lines that were printed on the external program’s standard error.

  • :status => exit code returned by the external program.

Examples:

require 'libis/tools/command'
result = ::Libis::Tools::Command.run('ls', '-l', File.absolute_path(__FILE__))
p result # => {out: [...], err: [...], status: 0}

require 'libis/tools/command'
include ::Libis::Tools::Command
result = run('ls', '-l', File.absolute_path(__FILE__))
p result # => {out: [...], err: [...], status: 0}

Note that the Command class uses Open3#popen3 internally. All arguments supplied to Command#run are passed to the popen3 call. Unfortunately some older JRuby versions have some known issues with popen3. Please use and test carefully in JRuby environments.

Class Method Summary collapse

Class Method Details

.run(cmd, *opts) ⇒ Hash

Run an external program and return status, stdout and stderr.

Parameters:

  • cmd (String)

    program name

  • opts (Array<String>)

    optional list of command line arguments

Returns:

  • (Hash)

    a Hash with:

    • :status (Integer) - the exit status of the command

    • :out (Array<String>) - the stdout output of the command

    • :err (Array<String>)- the stderr output of the command



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/libis/tools/command.rb', line 39

def self.run(cmd, *opts)
  result = {
      status: 999,
      out: [],
      err: []
  }
  begin
    Open3.popen3(cmd, *opts) do |_, output, error, thread|
      output = output.read
      error = error.read
      result[:out] = output.split("\n").map(&:chomp)
      result[:err] = error.split("\n").map(&:chomp)
      result[:status] = thread.value.exitstatus rescue nil
    end

  rescue StandardError => e
    result[:err] = [e.class.name, e.message]

  end

  result

end