Class: SSHKit::Command

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

Overview

Author:

  • Lee Hambley

Constant Summary collapse

Failed =
Class.new(SSHKit::StandardError)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Command

Initialize a new Command object

command name, with optional variadaric args nothing in stdin or stdout

Parameters:

  • A (Array)

    list of arguments, the first is considered to be the

Raises:

  • (ArgumentError)

22
23
24
25
26
27
28
29
30
# File 'lib/sshkit/command.rb', line 22

def initialize(*args)
  raise ArgumentError, "Must pass arguments to Command.new" if args.empty?
  @options = default_options.merge(args.extract_options!)
  @command = sanitize_command(args.shift)
  @args    = args
  @options.symbolize_keys!
  @stdout, @stderr, @full_stdout, @full_stderr = String.new, String.new, String.new, String.new
  @uuid = Digest::SHA1.hexdigest(SecureRandom.random_bytes(10))[0..7]
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args


13
14
15
# File 'lib/sshkit/command.rb', line 13

def args
  @args
end

#commandObject (readonly)

Returns the value of attribute command


13
14
15
# File 'lib/sshkit/command.rb', line 13

def command
  @command
end

#exit_statusObject

Returns the value of attribute exit_status


13
14
15
# File 'lib/sshkit/command.rb', line 13

def exit_status
  @exit_status
end

#full_stderrObject (readonly)

Returns the value of attribute full_stderr


13
14
15
# File 'lib/sshkit/command.rb', line 13

def full_stderr
  @full_stderr
end

#full_stdoutObject (readonly)

Returns the value of attribute full_stdout


13
14
15
# File 'lib/sshkit/command.rb', line 13

def full_stdout
  @full_stdout
end

#optionsObject (readonly)

Returns the value of attribute options


13
14
15
# File 'lib/sshkit/command.rb', line 13

def options
  @options
end

#startedObject

Returns the value of attribute started


13
14
15
# File 'lib/sshkit/command.rb', line 13

def started
  @started
end

#started_atObject (readonly)

Returns the value of attribute started_at


13
14
15
# File 'lib/sshkit/command.rb', line 13

def started_at
  @started_at
end

#uuidObject (readonly)

Returns the value of attribute uuid


13
14
15
# File 'lib/sshkit/command.rb', line 13

def uuid
  @uuid
end

Class Method Details

.shellescape_except_tilde(file) ⇒ Object

allow using home directory but escape everything else like spaces etc


223
224
225
# File 'lib/sshkit/command.rb', line 223

def self.shellescape_except_tilde(file)
  file.shellescape.gsub("\\~", "~")
end

Instance Method Details

#complete?Boolean Also known as: finished?

Returns:

  • (Boolean)

32
33
34
# File 'lib/sshkit/command.rb', line 32

def complete?
  !exit_status.nil?
end

#environment_hashObject


149
150
151
# File 'lib/sshkit/command.rb', line 149

def environment_hash
  (SSHKit.config.default_env || {}).merge(options[:env] || {})
end

#environment_stringObject


153
154
155
156
157
158
159
# File 'lib/sshkit/command.rb', line 153

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(/"/, '\"')
    %{#{key_string}="#{escaped_value}"}
  end.join(' ')
end

#failure?Boolean Also known as: failed?

Returns:

  • (Boolean)

51
52
53
# File 'lib/sshkit/command.rb', line 51

def failure?
  exit_status.to_i > 0
end

#group(&_block) ⇒ Object


183
184
185
186
187
188
# File 'lib/sshkit/command.rb', line 183

def group(&_block)
  return yield unless options[:group]
  "sg #{options[:group].to_s.shellescape} -c #{yield.shellescape}"
  # We could also use the so-called heredoc format perhaps:
  #"newgrp #{options[:group]} <<EOC \\\"%s\\\" EOC" % %Q{#{yield}}
end

#hostObject


125
126
127
# File 'lib/sshkit/command.rb', line 125

def host
  options[:host]
end

#in_background(&_block) ⇒ Object


173
174
175
176
# File 'lib/sshkit/command.rb', line 173

def in_background(&_block)
  return yield unless options[:run_in_background]
  "( nohup #{yield} > /dev/null & )"
end

#on_stderr(channel, data) ⇒ Object


82
83
84
85
86
# File 'lib/sshkit/command.rb', line 82

def on_stderr(channel, data)
  @stderr = data
  @full_stderr += data
  call_interaction_handler(:stderr, data, channel)
end

#on_stdout(channel, data) ⇒ Object


76
77
78
79
80
# File 'lib/sshkit/command.rb', line 76

def on_stdout(channel, data)
  @stdout = data
  @full_stdout += data
  call_interaction_handler(:stdout, data, channel)
end

#runtimeObject


101
102
103
104
# File 'lib/sshkit/command.rb', line 101

def runtime
  return nil unless complete?
  @finished_at - @started_at
end

#should_map?Boolean

Returns:

  • (Boolean)

140
141
142
# File 'lib/sshkit/command.rb', line 140

def should_map?
  !command.match(/\s/)
end

#started?Boolean

Returns:

  • (Boolean)

37
38
39
# File 'lib/sshkit/command.rb', line 37

def started?
  started
end

#stderrObject


66
67
68
69
# File 'lib/sshkit/command.rb', line 66

def stderr
  log_reader_deprecation('stderr')
  @stderr
end

#stderr=(new_value) ⇒ Object


71
72
73
74
# File 'lib/sshkit/command.rb', line 71

def stderr=(new_value)
  log_writer_deprecation('stderr')
  @stderr = new_value
end

#stdoutObject


56
57
58
59
# File 'lib/sshkit/command.rb', line 56

def stdout
  log_reader_deprecation('stdout')
  @stdout
end

#stdout=(new_value) ⇒ Object


61
62
63
64
# File 'lib/sshkit/command.rb', line 61

def stdout=(new_value)
  log_writer_deprecation('stdout')
  @stdout = new_value
end

#success?Boolean Also known as: successful?

Returns:

  • (Boolean)

46
47
48
# File 'lib/sshkit/command.rb', line 46

def success?
  exit_status.nil? ? false : exit_status.to_i == 0
end

#to_commandObject


190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/sshkit/command.rb', line 190

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_hashObject


106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/sshkit/command.rb', line 106

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_sObject


214
215
216
217
218
219
220
# File 'lib/sshkit/command.rb', line 214

def to_s
  if should_map?
    [SSHKit.config.command_map[command.to_sym], *Array(args)].join(' ')
  else
    command.to_s
  end
end

#umask(&_block) ⇒ Object


178
179
180
181
# File 'lib/sshkit/command.rb', line 178

def umask(&_block)
  return yield unless SSHKit.config.umask
  "umask #{SSHKit.config.umask} && #{yield}"
end

#user(&_block) ⇒ Object


167
168
169
170
171
# File 'lib/sshkit/command.rb', line 167

def user(&_block)
  return yield unless options[:user]
  env_string = environment_string
  "sudo -u #{options[:user].to_s.shellescape} #{env_string + " " unless env_string.empty?}-- sh -c #{yield.shellescape}"
end

#verbosityObject


129
130
131
132
133
134
135
136
137
138
# File 'lib/sshkit/command.rb', line 129

def verbosity
  if (vb = options[:verbosity])
    case vb
    when Symbol then return Logger.const_get(vb.to_s.upcase)
    when Integer then return vb
    end
  else
    Logger::INFO
  end
end

#with(&_block) ⇒ Object


161
162
163
164
165
# File 'lib/sshkit/command.rb', line 161

def with(&_block)
  env_string = environment_string
  return yield if env_string.empty?
  "( export #{env_string} ; #{yield} )"
end

#with_redactionObject


207
208
209
210
211
212
# File 'lib/sshkit/command.rb', line 207

def with_redaction
  new_args = args.map{|arg| arg.is_a?(Redaction) ? '[REDACTED]' : arg }
  redacted_cmd = dup
  redacted_cmd.instance_variable_set(:@args, new_args)
  redacted_cmd
end

#within(&_block) ⇒ Object


144
145
146
147
# File 'lib/sshkit/command.rb', line 144

def within(&_block)
  return yield unless options[:in]
  "cd #{self.class.shellescape_except_tilde(options[:in])} && #{yield}"
end