Class: BlueShell::Bash

Inherits:
Object
  • Object
show all
Defined in:
lib/blue_shell/bash.rb

Constant Summary collapse

BufferedReader =
java.io.BufferedReader
InputStreamReader =
java.io.InputStreamReader

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBash

Returns a new instance of Bash.



12
13
14
15
# File 'lib/blue_shell/bash.rb', line 12

def initialize
  @hooks     = { stderr: [], stdout: [] }
  @executing = false
end

Instance Attribute Details

#errObject (readonly)

Returns the value of attribute err.



10
11
12
# File 'lib/blue_shell/bash.rb', line 10

def err
  @err
end

#exitObject (readonly)

Returns the value of attribute exit.



10
11
12
# File 'lib/blue_shell/bash.rb', line 10

def exit
  @exit
end

#outObject (readonly)

Returns the value of attribute out.



10
11
12
# File 'lib/blue_shell/bash.rb', line 10

def out
  @out
end

Instance Method Details

#add_hook(type, lambda) ⇒ Object

Add a lambda to execute on every line of stdout. The lambda should accept one parameter, a string, the line of output.

Examples:

Pushing to the console

lambda { |line| puts line }

Parameters:

  • the (Symbol)

    stream to hook into (:stderr or :stdout)

  • the (Lambda)

    code to execute



23
24
25
# File 'lib/blue_shell/bash.rb', line 23

def add_hook(type, lambda)
  @hooks[type] << lambda
end

#execute!(command, timeout = 30) ⇒ Object

Execute the given command. Will block until the command completes. param [String] the command to execute in bash param [Integer] the number of seconds to wait for it to complete



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/blue_shell/bash.rb', line 30

def execute!(command, timeout = 30)
  # Executing via a file seems clunky, but it is a good way to
  # ensure everything happens exactly as we expect it to without 
  # trying to deal with escaping the world properly.
  file = Tempfile.new('command')

  begin
    file << command
    file.flush

    Timeout::timeout(timeout) do
      proc = runtime.exec("/bin/bash #{file.path}")

      @out = []
      @err = []

      # Must have a sink for stdout for the proc to exit
      out_thread = read_thread(:stdout, proc.getInputStream, @out)
      err_thread = read_thread(:stderr, proc.getErrorStream, @err)

      out_thread.join
      err_thread.join

      @out = @out.join("\n")
      @err = @err.join("\n")

      # Noticed some cases where the join isn't good enough in the wild.
      proc.waitFor

      @exit = proc.exitValue
    end
  ensure
    file.close
    file.unlink
  end
end