class SSHKit::Command

@author Lee Hambley

Constants

Failed

Attributes

args[R]
command[R]
exit_status[R]
full_stderr[R]
full_stdout[R]
options[R]
started[R]
started_at[R]

Public Class Methods

new(*args) click to toggle source

Initialize a new Command object

@param [Array] A list of arguments, the first is considered to be the command name, with optional variadaric args @return [Command] An un-started command object with no exit staus, and nothing in stdin or stdout

# File lib/sshkit/command.rb, line 21
def initialize(*args)
  raise ArgumentError, "Must pass arguments to Command.new" if args.empty?
  @options = default_options.merge(args.extract_options!)
  @command = args.shift.to_s.strip.to_sym
  @args    = args
  @options.symbolize_keys!
  sanitize_command!
  @stdout, @stderr, @full_stdout, @full_stderr = String.new, String.new, String.new, String.new
end

Public Instance Methods

complete?() click to toggle source
# File lib/sshkit/command.rb, line 31
def complete?
  !exit_status.nil?
end
Also aliased as: finished?
environment_hash() click to toggle source
# File lib/sshkit/command.rb, line 152
def environment_hash
  (SSHKit.config.default_env || {}).merge(options[:env] || {})
end
environment_string() click to toggle source
# File lib/sshkit/command.rb, line 156
def environment_string
  environment_hash.collect do |key,value|
    key_string = key.is_a?(Symbol) ? key.to_s.upcase : key.to_s
    escaped_value = value.to_s.gsub(/"/, '\"')
    %Q{#{key_string}="#{escaped_value}"}
  end.join(' ')
end
exit_status=(new_exit_status) click to toggle source
# File lib/sshkit/command.rb, line 91
def exit_status=(new_exit_status)
  @finished_at = Time.now
  @exit_status = new_exit_status

  if options[:raise_on_non_zero_exit] && exit_status > 0
    message = ""
    message += "#{command} exit status: " + exit_status.to_s + "\n"
    message += "#{command} stdout: " + (full_stdout.strip.empty? ? "Nothing written" : full_stdout.strip) + "\n"
    message += "#{command} stderr: " + (full_stderr.strip.empty? ? 'Nothing written' : full_stderr.strip) + "\n"
    raise Failed, message
  end
end
failed?()
Alias for: failure?
failure?() click to toggle source
# File lib/sshkit/command.rb, line 54
def failure?
  exit_status.to_i > 0
end
Also aliased as: failed?
finished?()
Alias for: complete?
group() { || ... } click to toggle source
# File lib/sshkit/command.rb, line 184
def group(&_block)
  return yield unless options[:group]
  "sg #{options[:group]} -c \\\"%s\\\"" % %Q{#{yield}}
  # We could also use the so-called heredoc format perhaps:
  #"newgrp #{options[:group]} <<EOC \\\"%s\\\" EOC" % %Q{#{yield}}
end
host() click to toggle source
# File lib/sshkit/command.rb, line 128
def host
  options[:host]
end
in_background() { || ... } click to toggle source
# File lib/sshkit/command.rb, line 174
def in_background(&_block)
  return yield unless options[:run_in_background]
  sprintf("( nohup %s > /dev/null & )", yield)
end
on_stderr(channel, data) click to toggle source
# File lib/sshkit/command.rb, line 85
def on_stderr(channel, data)
  @stderr = data
  @full_stderr += data
  call_interaction_handler(:stderr, data, channel)
end
on_stdout(channel, data) click to toggle source
# File lib/sshkit/command.rb, line 79
def on_stdout(channel, data)
  @stdout = data
  @full_stdout += data
  call_interaction_handler(:stdout, data, channel)
end
runtime() click to toggle source
# File lib/sshkit/command.rb, line 104
def runtime
  return nil unless complete?
  @finished_at - @started_at
end
should_map?() click to toggle source
# File lib/sshkit/command.rb, line 143
def should_map?
  !command.match(/\s/)
end
started=(new_started) click to toggle source
# File lib/sshkit/command.rb, line 40
def started=(new_started)
  @started_at = Time.now
  @started = new_started
end
started?() click to toggle source
# File lib/sshkit/command.rb, line 36
def started?
  started
end
stderr() click to toggle source
# File lib/sshkit/command.rb, line 69
def stderr
  log_reader_deprecation('stderr')
  @stderr
end
stderr=(new_value) click to toggle source
# File lib/sshkit/command.rb, line 74
def stderr=(new_value)
  log_writer_deprecation('stderr')
  @stderr = new_value
end
stdout() click to toggle source
# File lib/sshkit/command.rb, line 59
def stdout
  log_reader_deprecation('stdout')
  @stdout
end
stdout=(new_value) click to toggle source
# File lib/sshkit/command.rb, line 64
def stdout=(new_value)
  log_writer_deprecation('stdout')
  @stdout = new_value
end
success?() click to toggle source
# File lib/sshkit/command.rb, line 49
def success?
  exit_status.nil? ? false : exit_status.to_i == 0
end
Also aliased as: successful?
successful?()
Alias for: success?
to_command() click to toggle source
# File lib/sshkit/command.rb, line 191
def to_command
  return command.to_s unless should_map?
  within do
    umask do
      with do
        user do
          in_background do
            group do
              to_s
            end
          end
        end
      end
    end
  end
end
to_hash() click to toggle source
# File lib/sshkit/command.rb, line 109
def to_hash
  {
    command:     self.to_s,
    args:        args,
    options:     options,
    exit_status: exit_status,
    stdout:      full_stdout,
    stderr:      full_stderr,
    started_at:  @started_at,
    finished_at: @finished_at,
    runtime:     runtime,
    uuid:        uuid,
    started:     started?,
    finished:    finished?,
    successful:  successful?,
    failed:      failed?
  }
end
to_s() click to toggle source
# File lib/sshkit/command.rb, line 208
def to_s
  if should_map?
    [SSHKit.config.command_map[command.to_sym], *Array(args)].join(' ')
  else
    command.to_s
  end
end
umask() { || ... } click to toggle source
# File lib/sshkit/command.rb, line 179
def umask(&_block)
  return yield unless SSHKit.config.umask
  sprintf("umask #{SSHKit.config.umask} && %s", yield)
end
user() { || ... } click to toggle source
# File lib/sshkit/command.rb, line 169
def user(&_block)
  return yield unless options[:user]
  "sudo -u #{options[:user]} #{environment_string + " " unless environment_string.empty?}-- sh -c '%s'" % %Q{#{yield}}
end
uuid() click to toggle source
# File lib/sshkit/command.rb, line 45
def uuid
  @uuid ||= Digest::SHA1.hexdigest(SecureRandom.random_bytes(10))[0..7]
end
verbosity() click to toggle source
# File lib/sshkit/command.rb, line 132
def verbosity
  if (vb = options[:verbosity])
    case vb.class.name
    when 'Symbol' then return Logger.const_get(vb.to_s.upcase)
    when 'Fixnum' then return vb
    end
  else
    Logger::INFO
  end
end
with() { || ... } click to toggle source
# File lib/sshkit/command.rb, line 164
def with(&_block)
  return yield unless environment_hash.any?
  sprintf("( export #{environment_string} ; %s )", yield)
end
within() { || ... } click to toggle source
# File lib/sshkit/command.rb, line 147
def within(&_block)
  return yield unless options[:in]
  sprintf("cd #{options[:in]} && %s", yield)
end

Private Instance Methods

call_interaction_handler(stream_name, data, channel) click to toggle source
# File lib/sshkit/command.rb, line 237
def call_interaction_handler(stream_name, data, channel)
  interaction_handler = options[:interaction_handler]
  interaction_handler = MappingInteractionHandler.new(interaction_handler) if interaction_handler.kind_of?(Hash)
  interaction_handler.on_data(self, stream_name, data, channel) if interaction_handler.respond_to?(:on_data)
end
default_options() click to toggle source
# File lib/sshkit/command.rb, line 218
def default_options
  {
    raise_on_non_zero_exit: true,
    run_in_background:      false
  }
end
log_reader_deprecation(stream) click to toggle source
# File lib/sshkit/command.rb, line 243
def log_reader_deprecation(stream)
  SSHKit.config.deprecation_logger.log(
    "The #{stream} method on Command is deprecated. "          "The @#{stream} attribute will be removed in a future release. Use full_#{stream}() instead."
  )
end
log_writer_deprecation(stream) click to toggle source
# File lib/sshkit/command.rb, line 250
def log_writer_deprecation(stream)
  SSHKit.config.deprecation_logger.log(
    "The #{stream}= method on Command is deprecated. The @#{stream} attribute will be removed in a future release."
  )
end
sanitize_command!() click to toggle source
# File lib/sshkit/command.rb, line 225
def sanitize_command!
  command.to_s.strip!
  if command.to_s.match("\n")
    @command = String.new.tap do |cs|
      command.to_s.lines.each do |line|
        cs << line.strip
        cs << '; ' unless line == command.to_s.lines.to_a.last
      end
    end
  end
end