Class: Ronin::Core::CLI::CommandShell

Inherits:
Shell
  • Object
show all
Defined in:
lib/ronin/core/cli/command_shell.rb,
lib/ronin/core/cli/command_shell/command.rb
more...

Overview

Base class for all custom command shells.

Example

class HTTPShell < Ronin::Core::CLI::Shell

  shell_name 'http'

  command :get, usage: 'PATH [HEADERS...]',
                summary: 'Sends a GET request'
  def get(path,*headers)
    # ...
  end

  command :post, usage: 'PATH DATA [HEADERS...]',
                 summary: 'Sends a POST request'
  def post(path,data,*headers)
    # ...
  end

end

HTTPShell.start
# http> get /foo

Defined Under Namespace

Classes: Command

Constant Summary

Constants included from Banner

Banner::BANNER

Instance Attribute Summary

Attributes inherited from Shell

#prompt_sigil, #shell_name

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Shell

#initialize, #prompt, prompt_sigil, shell_name, start

Methods included from Banner

#print_banner

Constructor Details

This class inherits a constructor from Ronin::Core::CLI::Shell

Class Method Details

.command(name, method_name: name, usage: nil, completions: nil, summary:, help: summary) ⇒ Object

Registers a shell command.

Parameters:

  • name (Symbol)

    The name of the shell command.

  • method_name (Symbol) (defaults to: name)

    Optional method name to use. Defaults to the name argument.

  • usage (String, nil) (defaults to: nil)

    A usage string indicating the shell command's options/arguments.

  • completions (Array<String>, Symbol, nil) (defaults to: nil)

    The possible tab completion values, or a method name, to complete the command's arguments.

  • summary (String)

    A one-line summary of the shell command.

  • help (String) (defaults to: summary)

    Multi-line help output for the shell command.

[View source]

93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ronin/core/cli/command_shell.rb', line 93

def self.command(name, method_name: name,
                       usage: nil,
                       completions: nil,
                       summary: ,
                       help: summary)
  commands[name.to_s] = Command.new(name, method_name: method_name,
                                          usage:       usage,
                                          completions: completions,
                                          summary:     summary,
                                          help:        help.strip)
end

.commandsHash{String => CommandShell::Command}

The registered shell commands.

Returns:

[View source]

63
64
65
66
67
68
69
# File 'lib/ronin/core/cli/command_shell.rb', line 63

def self.commands
  @commands ||= if superclass <= CommandShell
                  superclass.commands.dup
                else
                  {}
                end
end

.parse_command(line) ⇒ String+

Parses a line of input.

Parameters:

  • line (String)

    A line of input.

Returns:

  • (String, Array<String>)

    The command name and any additional arguments.

[View source]

114
115
116
# File 'lib/ronin/core/cli/command_shell.rb', line 114

def self.parse_command(line)
  Shellwords.shellsplit(line)
end

Instance Method Details

#call(name, *args) ⇒ Boolean

Invokes the command with the matching name.

Parameters:

  • name (String)

    The command name.

  • args (Array<String>)

    Additional arguments for the command.

Returns:

  • (Boolean)

    Indicates whether the command was successfully executed.

Raises:

  • (NotImplementedError)

    The method for the command was not defined.

[View source]

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/ronin/core/cli/command_shell.rb', line 187

def call(name,*args)
  unless (command = self.class.commands[name])
    return command_missing(name,*args)
  end

  method_name = command.method_name

  unless respond_to?(method_name,false)
    raise(NotImplementedError,"#{self.class}##{method_name} was not defined for the #{name.inspect} command")
  end

  unless method_arity_check(method_name,args)
    return false
  end

  begin
    send(method_name,*args)
  rescue => error
    print_exception(error)
    print_error "an unhandled exception occurred in the #{name} command"
    return false
  end

  return true
end

#command_missing(name, *args) ⇒ Object

Default method that is called when an unknown command is called.

Parameters:

  • name (String)
  • args (Array<String>)
[View source]

220
221
222
223
# File 'lib/ronin/core/cli/command_shell.rb', line 220

def command_missing(name,*args)
  command_not_found(name)
  return false
end

#command_not_found(name) ⇒ Object

Prints an error message when an unknown command is given.

Parameters:

  • name (String)
[View source]

230
231
232
# File 'lib/ronin/core/cli/command_shell.rb', line 230

def command_not_found(name)
  print_error "unknown command: #{name}"
end

#complete(word, preposing) ⇒ Array<String>?

The partially input being tab completed.

Parameters:

  • word (String)

    The partial input being tab completed.

  • preposing (String)

    The optional command name that precedes the argument that's being tab completed.

Returns:

  • (Array<String>, nil)

    The possible completion values.

Raises:

  • (NotImplementedError)

    The command defined a completion method name but the command shell does not define the complete method name.

[View source]

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/ronin/core/cli/command_shell.rb', line 135

def complete(word,preposing)
  if preposing.empty?
    self.class.commands.keys.select { |name| name.start_with?(word) }
  else
    name = preposing.split(/\s+/,2).first

    if (command = self.class.commands[name])
      completions = case command.completions
                    when Array then command.completions
                    when Symbol
                      unless respond_to?(command.completions)
                        raise(NotImplementedError,"#{self.class}##{command.completions} was not defined")
                      end

                      send(command.completions,word,preposing)
                    end

      if completions
        completions.select { |arg| arg.start_with?(word) }
      end
    end
  end
end

#exec(command) ⇒ Boolean

Executes a command.

Parameters:

  • command (String)

    The command to execute.

Returns:

  • (Boolean)

    Indicates whether the command was successfully executed.

[View source]

168
169
170
# File 'lib/ronin/core/cli/command_shell.rb', line 168

def exec(command)
  call(*self.class.parse_command(command))
end

#help(command = nil) ⇒ Object

Prints all commands or help information for the given command.

Parameters:

  • command (String, nil) (defaults to: nil)

    Optional command name to print help information for.

[View source]

243
244
245
246
247
# File 'lib/ronin/core/cli/command_shell.rb', line 243

def help(command=nil)
  if command then help_command(command)
  else            help_commands
  end
end

#quitObject

Quits the shell.

Since:

  • 0.2.0

[View source]

256
257
258
# File 'lib/ronin/core/cli/command_shell.rb', line 256

def quit
  exit
end