Class: Derelict::Executer

Inherits:
Object
  • Object
show all
Includes:
Utils::Logger
Defined in:
lib/derelict/executer.rb

Overview

Executes an external (shell) command “safely”

The safety involved is mainly ensuring that the command is gracefully terminated if this process is about to terminate.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils::Logger

#logger

Constructor Details

#initialize(options = {}) ⇒ Executer

Initializes an Executer instance with particular options

* options: A hash of options, with the following (symbol) keys:
   * :mode:      Controls how the process' output is given to
                 the block, one of :chars (pass each character
                 one by one, retrieved with getc), or :lines
                 (pass only whole lines, retrieved with gets).
                 (optional, defaults to :lines)
   * :no_buffer: If true, the process' stdout and stderr won't
                 be collected in the stdout and stderr
                 properties, and will only be passed to the
                 block (optional, defaults to false)


46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/derelict/executer.rb', line 46

def initialize(options = {})
  @options = {:mode => :lines, :no_buffer => false}.merge(options)

  logger.info "Initializing with options: #{@options.inspect}"

  if @options[:mode] == :chars
    @reader = proc {|s| s.getc }
  else
    @reader = proc {|s| s.gets }
  end

  @mutex = Mutex.new
  reset
end

Instance Attribute Details

#pidObject (readonly)

Returns the value of attribute pid.



10
11
12
# File 'lib/derelict/executer.rb', line 10

def pid
  @pid
end

#stderrObject (readonly)

Returns the value of attribute stderr.



10
11
12
# File 'lib/derelict/executer.rb', line 10

def stderr
  @stderr
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



10
11
12
# File 'lib/derelict/executer.rb', line 10

def stdout
  @stdout
end

Class Method Details

.execute(command, options = {}, &block) ⇒ Object

Executes command and returns after execution

* command: A string containing the command to run
* options: A hash of options, with the following (symbol) keys:
   * :mode:      Controls how the process' output is given to
                 the block, one of :chars (pass each character
                 one by one, retrieved with getc), or :lines
                 (pass only whole lines, retrieved with gets).
                 (optional, defaults to :lines)
   * :no_buffer: If true, the process' stdout and stderr won't
                 be collected in the stdout and stderr
                 properties, and will only be passed to the
                 block (optional, defaults to false)
* block:   Gets passed stdout and stderr every time the process
           outputs to each stream (first parameter is stdout,
           second parameter is stderr; only one will contain
           data, the other will be nil)


29
30
31
# File 'lib/derelict/executer.rb', line 29

def self.execute(command, options = {}, &block)
  self.new(options).execute(command, &block)
end

Instance Method Details

#execute(command, &block) ⇒ Object

Executes command and returns after execution

* command: A string containing the command to run
* block:   Gets passed stdout and stderr every time the process
           outputs to each stream (first parameter is stdout,
           second parameter is stderr; only one will contain
           data, the other will be nil)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/derelict/executer.rb', line 68

def execute(command, &block)
  logger.info "Executing command '#{command}'"
  reset
  pid, stdin, stdout_stream, stderr_stream = Open4::popen4(command)
  @pid = pid
  stdin.close rescue nil

  save_exit_status(pid)
  forward_signals_to(pid) do
    handle_streams stdout_stream, stderr_stream, &block
  end

  self
ensure
  logger.debug "Closing stdout and stderr streams for process"
  stdout.close rescue nil
  stderr.close rescue nil
end

#success?Boolean

Determines whether the last command was successful or not

If the command’s exit status was zero, this will return true. If the command’s exit status is anything else, this will return false. If a command is currently running, this will return nil.

Returns:

  • (Boolean)


92
93
94
# File 'lib/derelict/executer.rb', line 92

def success?
  @success
end