class Shell::CommandProcessor

In order to execute a command on your OS, you need to define it as a Shell method.

Alternatively, you can execute any command via #system even if it is not defined.

Constants

NoDelegateMethods

Public Class Methods

alias_command(alias, command, *options) → self click to toggle source

Creates a command alias at the given alias for the given command, passing any options along with it.

Shell::CommandProcessor.alias_command "lsC", "ls", "-CBF", "--show-control-chars"
Shell::CommandProcessor.alias_command("lsC", "ls"){|*opts| ["-CBF", "--show-control-chars", *opts]}
# File lib/shell/command-processor.rb, line 438
def self.alias_command(ali, command, *opts)
  ali = ali.id2name if ali.kind_of?(Symbol)
  command = command.id2name if command.kind_of?(Symbol)
  begin
    if iterator?
      @alias_map[ali.intern] = proc

      eval((d = %Q[def #{ali}(*opts)
                      @shell.__send__(:#{command},
                                      *(CommandProcessor.alias_map[:#{ali}].call *opts))
                    end]), nil, __FILE__, __LINE__ - 1)

    else
       args = opts.collect{|opt| '"' + opt + '"'}.join(",")
       eval((d = %Q[def #{ali}(*opts)
                      @shell.__send__(:#{command}, #{args}, *opts)
                    end]), nil, __FILE__, __LINE__ - 1)
    end
  rescue SyntaxError
    Shell.notify "warn: Can't alias #{ali} command: #{command}."
    Shell.notify("Definition of #{ali}: ", d)
    raise
  end
  Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
  Shell.notify("Definition of #{ali}: ", d,
         Shell.debug.kind_of?(Integer) && Shell.debug > 1)
  self
end
alias_map() click to toggle source

Returns a list of aliased commands

# File lib/shell/command-processor.rb, line 426
def self.alias_map
  @alias_map
end
def_system_command(command, path) → Shell::SystemCommand click to toggle source

Defines a command, registering path as a Shell method for the given command.

Shell::CommandProcessor.def_system_command "ls"
  #=> Defines ls.

Shell::CommandProcessor.def_system_command "sys_sort", "sort"
  #=> Defines sys_sort as sort
# File lib/shell/command-processor.rb, line 399
def self.def_system_command(command, path = command)
  begin
    eval((d = %Q[def #{command}(*opts)
              SystemCommand.new(@shell, '#{path}', *opts)
           end]), nil, __FILE__, __LINE__ - 1)
  rescue SyntaxError
    Shell.notify "warn: Can't define #{command} path: #{path}."
  end
  Shell.notify "Define #{command} path: #{path}.", Shell.debug?
  Shell.notify("Definition of #{command}: ", d,
         Shell.debug.kind_of?(Integer) && Shell.debug > 1)
end
initialize() click to toggle source
# File lib/shell/command-processor.rb, line 37
def self.initialize

  install_builtin_commands

  # define CommandProcessor#methods to Shell#methods and Filter#methods
  for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
    add_delegate_command_to_shell(m)
  end

  def self.method_added(id)
    add_delegate_command_to_shell(id)
  end
end
method_added(id) click to toggle source
# File lib/shell/command-processor.rb, line 46
def self.method_added(id)
  add_delegate_command_to_shell(id)
end
new(shell) click to toggle source
# File lib/shell/command-processor.rb, line 68
def initialize(shell)
  @shell = shell
  @system_commands = {}
end
run_config() click to toggle source

include run file.

# File lib/shell/command-processor.rb, line 54
def self.run_config
  rc = "~/.rb_shell"
  begin
    load File.expand_path(rc) if ENV.key?("HOME")
  rescue LoadError, Errno::ENOENT
  rescue
    print "load error: #{rc}\n"
    print $!.class, ": ", $!, "\n"
    for err in $@[0, $@.size - 2]
      print "\t", err, "\n"
    end
  end
end
unalias_command(alias) → self click to toggle source

Unaliases the given alias command.

# File lib/shell/command-processor.rb, line 471
def self.unalias_command(ali)
  ali = ali.id2name if ali.kind_of?(Symbol)
  @alias_map.delete ali.intern
  undef_system_command(ali)
end
undef_system_command(command) → self click to toggle source

Undefines a command

# File lib/shell/command-processor.rb, line 416
def self.undef_system_command(command)
  command = command.id2name if command.kind_of?(Symbol)
  remove_method(command)
  Shell.module_eval{remove_method(command)}
  Filter.module_eval{remove_method(command)}
  self
end

Public Instance Methods

[](command, file1, file2=nil)

See #test

Alias for: test
append(to, filter) click to toggle source
# File lib/shell/command-processor.rb, line 318
def append(to, filter)
  case to
  when String
    AppendFile.new(@shell, to, filter)
  when IO
    AppendIO.new(@shell, to, filter)
  else
    Shell.Fail Error::CantApplyMethod, "append", to.class
  end
end
cat(*filename) → Cat click to toggle source

Returns a Cat object, for the given filenames

# File lib/shell/command-processor.rb, line 303
def cat(*filenames)
  Cat.new(@shell, *filenames)
end
concat(*jobs) → Concat click to toggle source

Returns a Concat object, for the given jobs

# File lib/shell/command-processor.rb, line 341
def concat(*jobs)
  Concat.new(@shell, *jobs)
end
echo(*strings) → Echo click to toggle source

Returns a Echo object, for the given strings

# File lib/shell/command-processor.rb, line 295
def echo(*strings)
  Echo.new(@shell, *strings)
end
expand_path(path) click to toggle source

#expand_path

  path:   String
  return: String
returns the absolute path for <path>
# File lib/shell/command-processor.rb, line 79
def expand_path(path)
  @shell.expand_path(path)
end
find_system_command(command) click to toggle source

private functions

# File lib/shell/command-processor.rb, line 358
def find_system_command(command)
  return command if /^\// =~ command
  case path = @system_commands[command]
  when String
    if exists?(path)
      return path
    else
      Shell.Fail Error::CommandNotFound, command
    end
  when false
    Shell.Fail Error::CommandNotFound, command
  end

  for p in @shell.system_path
    path = join(p, command)
    begin
      st = File.stat(path)
    rescue SystemCallError
      next
    else
      next unless st.executable? and !st.directory?
      @system_commands[command] = path
      return path
    end
  end
  @system_commands[command] = false
  Shell.Fail Error::CommandNotFound, command
end
foreach(path, record_separator) → Enumerator click to toggle source
foreach(path, record_separator) { block }

See IO.foreach when path is a file.

See Dir.foreach when path is a directory.

# File lib/shell/command-processor.rb, line 91
def foreach(path = nil, *rs)
  path = "." unless path
  path = expand_path(path)

  if File.directory?(path)
    Dir.foreach(path){|fn| yield fn}
  else
    IO.foreach(path, *rs){|l| yield l}
  end
end
glob(pattern) → Glob click to toggle source
def sort(*filenames)
  Sort.new(self, *filenames)
end

Returns a Glob filter object, with the given pattern object

# File lib/shell/command-processor.rb, line 314
def glob(pattern)
  Glob.new(@shell, pattern)
end
mkdir(path) click to toggle source

Same as Dir.mkdir, except multiple directories are allowed.

# File lib/shell/command-processor.rb, line 200
def mkdir(*path)
  @shell.check_point
  notify("mkdir #{path.join(' ')}")

  perm = nil
  if path.last.kind_of?(Integer)
    perm = path.pop
  end
  for dir in path
    d = expand_path(dir)
    if perm
      Dir.mkdir(d, perm)
    else
      Dir.mkdir(d)
    end
    File.chmod(d, 0666 & ~@shell.umask) if @shell.umask
  end
  Void.new(@shell)
end
notify(*opts) { |mes| ... } click to toggle source

%pwd, %cwd -> @pwd

# File lib/shell/command-processor.rb, line 346
def notify(*opts)
  Shell.notify(*opts) {|mes|
    yield mes if iterator?

    mes.gsub!("%pwd", "#{@cwd}")
    mes.gsub!("%cwd", "#{@cwd}")
  }
end
open(path, mode, permissions) → Enumerator click to toggle source
open(path, mode, permissions) { block }

See IO.open when path is a file.

See Dir.open when path is a directory.

# File lib/shell/command-processor.rb, line 110
def open(path, mode = nil, perm = 0666, &b)
  path = expand_path(path)
  if File.directory?(path)
    Dir.open(path, &b)
  else
    if @shell.umask
      f = File.open(path, mode, perm)
      File.chmod(perm & ~@shell.umask, path)
      if block_given?
        f.each(&b)
      end
      f
    else
      File.open(path, mode, perm, &b)
    end
  end
end
out(device) { block } click to toggle source

Calls device.print on the result passing the block to transact

# File lib/shell/command-processor.rb, line 287
def out(dev = STDOUT, &block)
  dev.print transact(&block)
end
rehash click to toggle source

Clears the command hash table.

# File lib/shell/command-processor.rb, line 258
def rehash
  @system_commands = {}
end
rmdir(path) click to toggle source

Same as Dir.rmdir, except multiple directories are allowed.

# File lib/shell/command-processor.rb, line 224
def rmdir(*path)
  @shell.check_point
  notify("rmdir #{path.join(' ')}")

  for dir in path
    Dir.rmdir(expand_path(dir))
  end
  Void.new(@shell)
end
system(command, *options) → SystemCommand click to toggle source

Executes the given command with the options parameter.

Example:

print sh.system("ls", "-l")
sh.system("ls", "-l") | sh.head > STDOUT
# File lib/shell/command-processor.rb, line 243
def system(command, *opts)
  if opts.empty?
    if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
      return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
    else
      command, *opts = command.split(/\s+/)
    end
  end
  SystemCommand.new(@shell, find_system_command(command), *opts)
end
tee(file) → Tee click to toggle source

Returns a Tee filter object, with the given file command

# File lib/shell/command-processor.rb, line 333
def tee(file)
  Tee.new(@shell, file)
end
test(command, file1, file2) → true or false click to toggle source
[command, file1, file2] → true or false

Tests if the given command exists in file1, or optionally file2.

Example:

sh[?e, "foo"]
sh[:e, "foo"]
sh["e", "foo"]
sh[:exists?, "foo"]
sh["exists?", "foo"]
# File lib/shell/command-processor.rb, line 162
def test(command, file1, file2=nil)
  file1 = expand_path(file1)
  file2 = expand_path(file2) if file2
  command = command.id2name if command.kind_of?(Symbol)

  case command
  when Integer
    if file2
      top_level_test(command, file1, file2)
    else
      top_level_test(command, file1)
    end
  when String
    if command.size == 1
      if file2
        top_level_test(command, file1, file2)
      else
        top_level_test(command, file1)
      end
    else
      unless FileTest.methods(false).include?(command.to_sym)
        raise "unsupported command: #{ command }"
      end
      if file2
        FileTest.send(command, file1, file2)
      else
        FileTest.send(command, file1)
      end
    end
  end
end
Also aliased as: top_level_test, []
top_level_test(command, file1, file2=nil)

See #test

Alias for: test
transact { block } click to toggle source

Executes a block as self

Example:

sh.transact { system("ls", "-l") | head > STDOUT }
# File lib/shell/command-processor.rb, line 274
def transact(&block)
  begin
    @shell.instance_eval(&block)
  ensure
    check_point
  end
end