Module: Open4ssh

Defined in:
lib/open4ssh.rb,
lib/open4ssh/version.rb

Overview

Open4ssh is a small convenience wrapper for net-ssh. Its intended and primary purpose is to provide pragmatic execution of shell commands on a remote host via SSH.

It provides the following functions:

  • Open4ssh.capture to execute one command on a remote host via SSH and get the console output back.

  • Open4ssh.capture3 to execute one command on a remote host via SSH and get the exit code, standard out, standard error of the command back.

  • Open4ssh.capture4 to execute a sequence of commands on a remote host via SSH and get all return values (exit code, standard out, standard error, command) back.

  • Open4ssh.success to evaluate whether a sequence of commands was successful.

  • Open4ssh.stdout to get all standard out messages of a sequence of commands.

  • Open4ssh.stderr to get all standard error messages of a sequence of commands.

  • Open4ssh.console to get all console output (union of standard out and standard error messages) of a sequence of commands.

Examples:

console = Open4ssh.capture(
    host: 'remote.host.io',
    user: 'nane',
    pwd: 'secret',
    cmd: 'ls -la'
)
puts console

Author:

  • Nane Kratzke

Constant Summary collapse

VERSION =

Version of Open4ssh according to semantic versioning

"0.2.1"

Class Method Summary collapse

Class Method Details

.capture(host: '', user: '', port: 22, key: '', pwd: '', cmd: '') ⇒ String

Executes a shell command on a remote host via SSH and captures the console output.

Examples:

stdout = Open4ssh.capture(
    host: 'remote.host.io',
    user: 'nane',
    pwd: 'secret',
    cmd: 'ls -la'
)
puts stdout

Parameters:

  • host (String) (defaults to: '')

    DNS name or IP address of the remote host (required)

  • port (Integer) (defaults to: 22)

    Port (defaults to 22)

  • user (String) (defaults to: '')

    User name (required)

  • key (Path) (defaults to: '')

    Path to a key file (.pem) if user logs in via keyfile (not required if password is provided)

  • pwd (String) (defaults to: '')

    Password of user (not required if key is provided)

  • cmd (String) (defaults to: '')

    valid shell command string to be executed on host (required)

Returns:

  • (String)

    console output of executed command (output includes stdout and stderr)

Raises:

  • (One of Net::SSH::Exceptions)

    In case of net::ssh errors due to connection problems, authentication errors, timeouts, .…



51
52
53
54
55
56
57
58
59
60
# File 'lib/open4ssh.rb', line 51

def self.capture(host: '', user: '', port: 22, key: '', pwd: '', cmd: '')
  stdout = ""
  keys = [key]

  Net::SSH.start(host, user, port: port, password: pwd, keys: keys, paranoid: false) do |ssh|
    stdout = ssh.exec!(cmd)
  end

  return stdout
end

.capture3(host: '', user: '', port: 22, key: '', pwd: '', cmd: '', verbose: false) ⇒ exit_code, ...

Executes one shell command on a remote host via SSH and captures it exit code, stdout and stderr.

Examples:

exit_code, std_err, std_out = Open4ssh.capture3(
  host: 'remote.host.io',
  user: 'nane',
  pwd: 'secret',
  cmd: 'ls -la'
)

Parameters:

  • host (String) (defaults to: '')

    DNS name or IP address of the remote host (required)

  • port (Integer) (defaults to: 22)

    Port (defaults to 22)

  • user (String) (defaults to: '')

    User name (required)

  • key (Path) (defaults to: '')

    Path to a key file (.pem) if user logs in via keyfile (not required if password is provided)

  • pwd (String) (defaults to: '')

    Password of user (not required if key is provided)

  • cmd (String) (defaults to: '')

    shell command string to be executed on host (required)

  • verbose (Bool) (defaults to: false)

    console outputs are plotted to stdout/stderr if set (defaults to false)

Returns:

  • (exit_code, std_out, std_err)

    exit_code, stdout, stderr of executed command

Raises:

  • (One of Net::SSH::Exceptions)

    In case of net::ssh errors due to connection problems, authentication errors, timeouts, .…



83
84
85
86
87
88
89
# File 'lib/open4ssh.rb', line 83

def self.capture3(host: '', user: '', port: 22, key: '', pwd: '', cmd: '', verbose: false)
  returns = self.capture4(host: host, user: user, port: port, key: key, pwd: pwd, cmd: [cmd], verbose: verbose)
  exit_code = returns.last[0]
  std_out = returns.last[1]
  std_err = returns.last[2]
  return exit_code, std_out, std_err
end

.capture4(host: '', user: '', port: 22, key: '', pwd: '', cmd: [], verbose: false) ⇒ Array<exit_code, std_out, std_err, command>

Executes a list of shell commands on a remote host via SSH and captures their exit codes, stdouts and stderrs. The commands are executed sequentially until a command terminates with an exit code not equal 0 (no success).

Examples:

exit_code, stderr, stdout, command = Open4ssh.capture4(
  host: 'remote.host.io',
  user: 'nane',
  key: '/path/to/your/sshkey.pem',
  cmd: [
  "touch helloworld.txt",
  "cat helloworld.txt",
  "echo 'Hello World' >> helloworld.txt",
  "cat helloworld.txt",
  "rm helloworld.txt"
]).last

Parameters:

  • host (String) (defaults to: '')

    DNS name or IP address of the remote host (required)

  • port (Integer) (defaults to: 22)

    Port (defaults to 22)

  • user (String) (defaults to: '')

    User name (required)

  • key (Path) (defaults to: '')

    Path to a key file (.pem) if user logs in via keyfile (not required if password is provided)

  • pwd (String) (defaults to: '')

    Password of user (not required if key is provided)

  • cmd (Array<String>) (defaults to: [])

    List of valid shell command strings to be executed on host (required)

  • verbose (Bool) (defaults to: false)

    console outputs are plotted to stdout/stderr if set (defaults to false)

Returns:

  • (Array<exit_code, std_out, std_err, command>)

    List of exit_code, stdout, stderr and executed commands

Raises:

  • (One of Net::SSH::Exceptions)

    In case of net::ssh errors due to connection problems, authentication errors, timeouts, .…



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/open4ssh.rb', line 118

def self.capture4(host: '', user: '', port: 22, key: '', pwd: '', cmd: [], verbose: false)
  keys    = [key]
  results = []

  Net::SSH.start(host, user, port: port, password: pwd, keys: keys, paranoid: false) do |ssh|
    # Execute command by command
    for command in cmd
      stdout   = ""
      stderr   = ""
      code     = nil
      channel = ssh.open_channel do |ch|
        ch.exec(command) do |c, success|
          c.close unless success

          c.on_data do |_, data|
            stdout += data
            $stdout.puts(data) if verbose
          end

          c.on_extended_data do |_, _, data|
            stderr += data
            $stderr.puts(data) if verbose
          end

          c.on_request('exit-status') { |_, data| code = data.read_long }
        end
      end
      channel.wait
      results << [code, stdout, stderr, command]

      # If last command was not successful stop execution
      if code != 0
        ssh.close
        return results
      end
    end
  end

  return results
end

.console(results) ⇒ String

Collects all console messages (stdout + stderr) of a list of executed shell commands.

Examples:

ecodes = Open4ssh.capture4(
  host: 'remote.host.io',
  user: 'nane',
  key: '/path/to/your/sshkey.pem',
  cmd: [
    "touch helloworld.txt",
    "cat helloworld.txt",
    "echo 'Hello World' >> helloworld.txt",
    "cat helloworld.txt",
    "rm helloworld.txt"
])

puts Open4ssh.console(ecodes) # Print collected console messages of all executed commands

Parameters:

  • results (Array<exit_code, std_out, std_err, command>)

    List of returns by executed commands as returned by capture4

Returns:

  • (String)

    All console messages (separated by line feed n)



267
268
269
270
# File 'lib/open4ssh.rb', line 267

def self.console(results)
  results.map { |result| "#{result[1]}#{result[2]}" }
         .select { |console| not console.strip.empty? } * ''
end

.stderr(results) ⇒ String

Collects all stderr messages of a list of executed shell commands.

Examples:

ecodes = Open4ssh.capture4(
  host: 'remote.host.io',
  user: 'nane',
  key: '/path/to/your/sshkey.pem',
  cmd: [
    "touch helloworld.txt",
    "cat helloworld.txt",
    "this will fail",
    "cat helloworld.txt",
    "rm helloworld.txt"
])

unless Open4ssh.success(ecodes)
   puts "Failure:"
   puts Open4ssh.stderr(ecodes) # Print collected stderr messages of all executed commands
end

Parameters:

  • results (Array<exit_code, std_out, std_err, command>)

    List of returns by executed commands as returned by capture4

Returns:

  • (String)

    All stderr messages (separated by line feed n)



241
242
243
244
# File 'lib/open4ssh.rb', line 241

def self.stderr(results)
  results.map { |result| result[2] }
         .select { |stderr| not stderr.strip.empty? } * ''
end

.stdout(results) ⇒ String

Collects all stdout messages of a list of executed shell commands.

Examples:

ecodes = Open4ssh.capture4(
  host: 'remote.host.io',
  user: 'nane',
  key: '/path/to/your/sshkey.pem',
  cmd: [
    "touch helloworld.txt",
    "cat helloworld.txt",
    "echo 'Hello World' >> helloworld.txt",
    "cat helloworld.txt",
    "rm helloworld.txt"
])

if Open4ssh.success(ecodes)
   puts "Success:"
   puts Open4ssh.stdout(ecodes) # Print collected stdout messages of all executed commands
end

Parameters:

  • results (Array<exit_code, std_out, std_err, command>)

    List of returns by executed commands as returned by capture4

Returns:

  • (String)

    All stdout messages (separated by line feed n)



212
213
214
215
# File 'lib/open4ssh.rb', line 212

def self.stdout(results)
  results.map { |result| result[1] }
         .select { |stdout| not stdout.strip.empty? } * ''
end

.success(results) ⇒ Bool

Determines whether a list of shell commands has been executed successfully.

Examples:

ecodes = Open4ssh.capture4(
  host: 'remote.host.io',
  user: 'nane',
  key: '/path/to/your/sshkey.pem',
  cmd: [
    "touch helloworld.txt",
    "cat helloworld.txt",
    "echo 'Hello World' >> helloworld.txt",
    "cat helloworld.txt",
    "rm helloworld.txt"
])

if Open4ssh.success(ecodes)
   puts "Success:"
   puts Open4ssh.console(ecodes) # Print collected console outputs of all executed commands
end

Parameters:

  • results (Array<exit_code, std_out, std_err, command>)

    List of returns by executed commands as returned by capture4

Returns:

  • (Bool)

    true, if all exit codes are 0;

  • (Bool)

    false, otherwise



184
185
186
# File 'lib/open4ssh.rb', line 184

def self.success(results)
  results.select { |result| result[0] != 0 }.empty?
end