Module: Shells::BashCommon

Included in:
SerialBashShell, SshBashShell
Defined in:
lib/shells/bash_common.rb

Overview

Provides some common functionality for bash-like shells.

Instance Method Summary collapse

Instance Method Details

#read_file(path, use_method = nil) ⇒ Object

Reads from a file on the device.



10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/shells/bash_common.rb', line 10

def read_file(path, use_method = nil)
  if use_method
    use_method = use_method.to_sym
    raise ArgumentError, "use_method (#{use_method.inspect}) is not a valid method." unless file_methods.include?(use_method)
    raise Shells::ShellError, "The #{use_method} binary is not available with this shell." unless which(use_method)
    send "read_file_#{use_method}", path
  elsif default_file_method
    return send "read_file_#{default_file_method}", path
  else
    raise Shells::ShellError, 'No supported binary to encode/decode files.'
  end
end

#sudo_exec(command, options = {}, &block) ⇒ Object

Executes an elevated command using the ‘sudo’ command.



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/shells/bash_common.rb', line 40

def sudo_exec(command, options = {}, &block)
  sudo_prompt = '[sp:'
  sudo_match = /\n\[sp:$/m
  sudo_strip = /\[sp:[^\n]*\n/m
  ret = exec("sudo -p \"#{sudo_prompt}\" bash -c \"#{command.gsub('"', '\\"')}\"", options) do |data,type|
    test_data = data.to_s
    desired_length = sudo_prompt.length + 1 # prefix a NL before the prompt.

    # pull from the current stdout to get the full test data, but only if we received some new data.
    if test_data.length > 0 && test_data.length < desired_length
      test_data = stdout[-desired_length..-1].to_s
    end

    if test_data =~ sudo_match
      self.options[:password]
    else
      if block
        block.call(data, type)
      else
        nil
      end
    end
  end
  # remove the sudo prompts.
  ret.gsub(sudo_strip, '')
end

#sudo_exec_for_code(command, options = {}, &block) ⇒ Object

Executes a command specifically for the exit code.

Does not return the output of the command, only the exit code.



71
72
73
74
75
# File 'lib/shells/bash_common.rb', line 71

def sudo_exec_for_code(command, options = {}, &block)
  options = (options || {}).merge(retrieve_exit_code: true, on_non_zero_exit_code: :ignore)
  sudo_exec command, options, &block
  last_exit_code
end

#sudo_exec_ignore_code(command, options = {}, &block) ⇒ Object

Executes a command ignoring any exit code.

Returns the output of the command and does not even retrieve the exit code.



81
82
83
84
# File 'lib/shells/bash_common.rb', line 81

def sudo_exec_ignore_code(command, options = {}, &block)
  options = (options || {}).merge(retrieve_exit_code: false, on_non_zero_exit_code: :ignore)
  sudo_exec command, options, &block
end

#write_file(path, data, use_method = nil) ⇒ Object

Writes to a file on the device.



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/shells/bash_common.rb', line 25

def write_file(path, data, use_method = nil)
  if use_method
    use_method = use_method.to_sym
    raise ArgumentError, "use_method (#{use_method.inspect}) is not a valid method." unless file_methods.include?(use_method)
    raise Shells::ShellError, "The #{use_method} binary is not available with this shell." unless which(use_method)
    send "write_file_#{use_method}", path, data
  elsif default_file_method
    return send "write_file_#{default_file_method}", path, data
  else
    raise Shells::ShellError, 'No supported binary to encode/decode files.'
  end
end