Class: Backticks::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/backticks/command.rb

Overview

Represents a running process; provides mechanisms for capturing the process’s output, passing input, waiting for the process to end, and learning its exitstatus.

Interactive commands print their output to Ruby’s STDOUT and STDERR in realtime, and also pass input from Ruby’s STDIN to the command’s stdin.

Constant Summary collapse

FOREVER =

Time value that is used internally when a user is willing to wait “forever” for the command.

Using a definite time-value helps simplify the looping logic internally, but it does mean that this class will stop working in February of 2106. You have been warned!

Time.at(2**32-1).freeze
CHUNK =

Number of bytes to read from the command in one “chunk”.

1_024

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pid, stdin, stdout, stderr) ⇒ Command

Watch a running command.



27
28
29
30
31
32
33
34
35
36
# File 'lib/backticks/command.rb', line 27

def initialize(pid, stdin, stdout, stderr)
  @pid = pid
  @stdin = stdin
  @stdout = stdout
  @stderr = stderr

  @captured_input  = String.new.force_encoding(Encoding::BINARY)
  @captured_output = String.new.force_encoding(Encoding::BINARY)
  @captured_error  = String.new.force_encoding(Encoding::BINARY)
end

Instance Attribute Details

#captured_errorString (readonly)

Returns all data captured (so far) from child’s stdin/stdout/stderr.

Returns:

  • (String)

    all data captured (so far) from child’s stdin/stdout/stderr



24
25
26
# File 'lib/backticks/command.rb', line 24

def captured_error
  @captured_error
end

#captured_inputString (readonly)

Returns all data captured (so far) from child’s stdin/stdout/stderr.

Returns:

  • (String)

    all data captured (so far) from child’s stdin/stdout/stderr



24
25
26
# File 'lib/backticks/command.rb', line 24

def captured_input
  @captured_input
end

#captured_outputString (readonly)

Returns all data captured (so far) from child’s stdin/stdout/stderr.

Returns:

  • (String)

    all data captured (so far) from child’s stdin/stdout/stderr



24
25
26
# File 'lib/backticks/command.rb', line 24

def captured_output
  @captured_output
end

#pidInteger (readonly)

Returns child process ID.

Returns:

  • (Integer)

    child process ID



21
22
23
# File 'lib/backticks/command.rb', line 21

def pid
  @pid
end

#statusString (readonly)

Returns all data captured (so far) from child’s stdin/stdout/stderr.

Returns:

  • (String)

    all data captured (so far) from child’s stdin/stdout/stderr



24
25
26
# File 'lib/backticks/command.rb', line 24

def status
  @status
end

Instance Method Details

#interactive?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/backticks/command.rb', line 38

def interactive?
  !@stdin.nil?
end

#join(limit = nil) ⇒ Object

Block until the command exits, or until limit seconds have passed. If interactive is true, pass user input to the command and print its output to Ruby’s output streams. If the time limit expires, return ‘nil`; otherwise, return self.

Parameters:

  • limit (Float, Integer) (defaults to: nil)

    number of seconds to wait before returning



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/backticks/command.rb', line 48

def join(limit=nil)
  if limit
    tf = Time.now + limit
  else
    tf = FOREVER
  end

  until (t = Time.now) >= tf
    capture(tf - t)
    res = Process.waitpid(@pid, Process::WNOHANG)
    if res
      @status = $?
      return self
    end
  end

  return nil
end