# 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 `Shell::CommandProcessor#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 439
    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 427
    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 400
    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 38
    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 47
    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 69
    def initialize(shell)
      @shell = shell
      @system_commands = {}
    end

run_config() click to toggle source

include run file.

    # File lib/shell/command-processor.rb, line 55
    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 472
    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 417
    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 `Shell::CommandProcessor#test`

Alias for: test
append(to, filter) click to toggle source

    # File lib/shell/command-processor.rb, line 319
    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 304
    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 342
    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 296
    def echo(*strings)
      Echo.new(@shell, *strings)
    end

expand_path(path) click to toggle source

`CommandProcessor#expand_path(path)`

      path:   String
      return: String
    returns the absolute path for <path>

    # File lib/shell/command-processor.rb, line 80
    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 359
    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 92
    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 315
    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 201
    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 347
    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 111
    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 288
    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 259
    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 225
    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 244
    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 334
    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 163
    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 `Shell::CommandProcessor#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 275
    def transact(&block)
      begin
        @shell.instance_eval(&block)
      ensure
        check_point
      end
    end

unlink(path) click to toggle source

See IO.unlink when `path` is a file.

See `Dir.unlink` when `path` is a directory.

    # File lib/shell/command-processor.rb, line 136
    def unlink(path)
      @shell.check_point

      path = expand_path(path)
      if File.directory?(path)
        Dir.unlink(path)
      else
        IO.unlink(path)
      end
      Void.new(@shell)
    end