Class: Shell::CommandProcessor
| Relationships & Source Files | |
| Inherits: | Object | 
| Defined in: | lib/shell/command-processor.rb | 
Overview
Constant Summary
- 
    NoDelegateMethods =
    
 # File 'lib/shell/command-processor.rb', line 33m
Class Method Summary
- 
    
      .alias_command(alias, command, *options)  ⇒ self 
    
    Creates a command alias at the given aliasfor the givencommand, passing anyoptionsalong with it.
- 
    
      .alias_map  
    
    Returns a list of aliased commands. 
- 
    
      .def_system_command(command, path)  ⇒ Shell::SystemCommand 
    
    Defines a command, registering pathas a::Shellmethod for the givencommand.
- .initialize
- 
    
      .install_builtin_commands  
    
    Delegates File methods into ::Shell, including the following commands:
- 
    
      .install_system_commands(prefix = "sys_")  
    
    Defines all commands in the default_system_path as ::Shellmethod, all with givenprefixappended to their names.
- .method_added(id)
- .new(shell) ⇒ CommandProcessor constructor
- 
    
      .run_config  
    
    include run file. 
- 
    
      .unalias_command(alias)  ⇒ self 
    
    Unaliases the given aliascommand.
- 
    
      .undef_system_command(command)  ⇒ self 
    
    Undefines a command. 
- .add_delegate_command_to_shell(id) Internal use only
- 
    
      .def_builtin_commands(delegation_class, command_specs)  
    
    Internal use only
    Delegates File and FileTest methods into ::Shell, including the following commands:
Instance Method Summary
- 
    
      #[](command, file1, file2 = nil)  
    
    Alias for #test. 
- #append(to, filter)
- 
    
      #cat(*filename)  ⇒ Cat 
    
    Returns a Catobject, for the givenfilenames
- #concat(*jobs) ⇒ Concat
- 
    
      #echo(*strings)  ⇒ Echo 
    
    Returns a Echoobject, for the givenstrings
- 
    
      #expand_path(path)  
    
    #expand_path(path). 
- 
    
      #find_system_command(command)  
    
    private functions. 
- 
    
      #foreach(path, record_separator)  ⇒ Enumerator 
    
    See IO.foreachwhenpathis a file.
- 
    
      #glob(pattern)  ⇒ Glob 
    
    def sort(*filenames). 
- 
    
      #mkdir(path)  
    
    Same as Dir.mkdir, except multiple directories are allowed.
- 
    
      #notify(*opts)  
    
    %pwd, %cwd -> @pwd. 
- 
    
      #open(path, mode, permissions)  ⇒ Enumerator 
    
    See IO.openwhenpathis a file.
- 
    
      #out(device)  
    
    Calls device.printon the result passing the block to #transact
- 
    
      #rehash  
    
    Clears the command hash table. 
- 
    
      #rmdir(path)  
    
    Same as Dir.rmdir, except multiple directories are allowed.
- 
    
      #system(command, *options)  ⇒ SystemCommand 
    
    Executes the given commandwith theoptionsparameter.
- 
    
      #tee(file)  ⇒ Tee 
    
    Returns a Teefilter object, with the givenfilecommand.
- 
    
      #test(command, file1, file2)  ⇒ Boolean 
      (also: #[])
    
    Tests if the given commandexists infile1, or optionallyfile2.
- 
    
      #top_level_test  
    
    See #test 
- 
    
      #transact  
    
    Executes a block as self. 
- 
    
      #unlink(path)  
    
    See IO.unlinkwhenpathis a file.
- #check_point (also: #finish_all_jobs) Internal use only
- 
    
      #finish_all_jobs  
    
    Internal use only
    Alias for #check_point. 
Constructor Details
    .new(shell)  ⇒ CommandProcessor 
  
# File 'lib/shell/command-processor.rb', line 69
def initialize(shell) @shell = shell @system_commands = {} end
Class Method Details
.add_delegate_command_to_shell(id)
# File 'lib/shell/command-processor.rb', line 579
def self.add_delegate_command_to_shell(id) # :nodoc: id = id.intern if id.kind_of?(String) name = id.id2name if Shell.method_defined?(id) Shell.notify "warn: override definition of Shell##{name}." Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n" Shell.module_eval "alias #{name}_org #{name}" end Shell.notify "method added: Shell##{name}.", Shell.debug? Shell.module_eval(%Q[def #{name}(*args, &block) begin @command_processor.__send__(:#{name}, *args, &block) rescue Exception $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` $@.delete_if{|s| /^\\(eval\\):/ =~ s} raise end end], __FILE__, __LINE__) if Shell::Filter.method_defined?(id) Shell.notify "warn: override definition of Shell::Filter##{name}." Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org." Filter.module_eval "alias #{name}_org #{name}" end Shell.notify "method added: Shell::Filter##{name}.", Shell.debug? Filter.module_eval(%Q[def #{name}(*args, &block) begin self | @shell.__send__(:#{name}, *args, &block) rescue Exception $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` $@.delete_if{|s| /^\\(eval\\):/ =~ s} raise end end], __FILE__, __LINE__) end
    .alias_command(alias, command, *options)  ⇒ self   
# 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
Returns a list of aliased commands
# File 'lib/shell/command-processor.rb', line 427
def self.alias_map @alias_map end
.def_builtin_commands(delegation_class, command_specs)
Delegates File and FileTest methods into ::Shell, including the following commands:
- 
Shell#blockdev?(file)
- 
Shell#chardev?(file)
- 
Shell#directory?(file)
- 
Shell#executable?(file)
- 
Shell#executable_real?(file)
- 
Shell#exist?(file)/Shell#exists?(file)
- 
Shell#file?(file)
- 
Shell#grpowned?(file)
- 
Shell#owned?(file)
- 
Shell#pipe?(file)
- 
Shell#readable?(file)
- 
Shell#readable_real?(file)
- 
Shell#setgid?(file)
- 
Shell#setuid?(file)
- 
Shell#size(file)/Shell#size?(file)
- 
Shell#socket?(file)
- 
Shell#sticky?(file)
- 
Shell#symlink?(file)
- 
Shell#writable?(file)
- 
Shell#writable_real?(file)
- 
Shell#zero?(file)
- 
Shell#syscopy(filename_from, filename_to)
- 
Shell#copy(filename_from, filename_to)
- 
Shell#move(filename_from, filename_to)
- 
Shell#compare(filename_from, filename_to)
- 
Shell#safe_unlink(*filenames)
- 
Shell#makedirs(*filenames)
- 
Shell#install(filename_from, filename_to, mode)
And also, there are some aliases for convenience:
- 
Shell#cmp <- Shell#compare
- 
Shell#mv <- Shell#move
- 
Shell#cp <- Shell#copy
- 
Shell#rm_f <- Shell#safe_unlink
- 
Shell#mkpath <- Shell#makedirs
# File 'lib/shell/command-processor.rb', line 520
def self.def_builtin_commands(delegation_class, command_specs) for meth, args in command_specs arg_str = args.collect{|arg| arg.downcase}.join(", ") call_arg_str = args.collect{ |arg| case arg when /^(FILENAME.*)$/ format("expand_path(%s)", $1.downcase) when /^(\*FILENAME.*)$/ # \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ") $1.downcase + '.collect{|fn| expand_path(fn)}' else arg end }.join(", ") d = %Q[def #{meth}(#{arg_str}) #{delegation_class}.#{meth}(#{call_arg_str}) end] Shell.notify "Define #{meth}(#{arg_str})", Shell.debug? Shell.notify("Definition of #{meth}: ", d, Shell.debug.kind_of?(Integer) && Shell.debug > 1) eval d end end
.def_system_command(command, path) ⇒ Shell::SystemCommand
# 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
[ GitHub ]# 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
.install_builtin_commands
Delegates File methods into ::Shell, including the following commands:
- 
Shell#atime(file)
- 
Shell#basename(file, *opt)
- 
Shell#chmod(mode, *files)
- 
Shell#chown(owner, group, *file)
- 
Shell#ctime(file)
- 
Shell#delete(*file)
- 
Shell#dirname(file)
- 
Shell#ftype(file)
- 
Shell#join(*file)
- 
Shell#link(file_from, file_to)
- 
Shell#lstat(file)
- 
Shell#mtime(file)
- 
Shell#readlink(file)
- 
Shell#rename(file_from, file_to)
- 
Shell#split(file)
- 
Shell#stat(file)
- 
Shell#symlink(file_from, file_to)
- 
Shell#truncate(file, length)
- 
Shell#utime(atime, mtime, *file)
# File 'lib/shell/command-processor.rb', line 637
def self.install_builtin_commands # method related File. # (exclude open/foreach/unlink) normal_delegation_file_methods = [ ["atime", ["FILENAME"]], ["basename", ["fn", "*opts"]], ["chmod", ["mode", "*FILENAMES"]], ["chown", ["owner", "group", "*FILENAME"]], ["ctime", ["FILENAMES"]], ["delete", ["*FILENAMES"]], ["dirname", ["FILENAME"]], ["ftype", ["FILENAME"]], ["join", ["*items"]], ["link", ["FILENAME_O", "FILENAME_N"]], ["lstat", ["FILENAME"]], ["mtime", ["FILENAME"]], ["readlink", ["FILENAME"]], ["rename", ["FILENAME_FROM", "FILENAME_TO"]], ["split", ["pathname"]], ["stat", ["FILENAME"]], ["symlink", ["FILENAME_O", "FILENAME_N"]], ["truncate", ["FILENAME", "length"]], ["utime", ["atime", "mtime", "*FILENAMES"]]] def_builtin_commands(File, normal_delegation_file_methods) alias_method :rm, :delete # method related FileTest def_builtin_commands(FileTest, FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]}) end
.install_system_commands(prefix = "sys_")
Defines all commands in the Shell.default_system_path as ::Shell method, all with given prefix appended to their names.
Any invalid character names are converted to _, and errors are passed to Shell.notify.
Methods already defined are skipped.
# File 'lib/shell/command-processor.rb', line 555
def self.install_system_commands(pre = "sys_") defined_meth = {} for m in Shell.methods defined_meth[m] = true end sh = Shell.new for path in Shell.default_system_path next unless sh.directory? path sh.cd path sh.foreach do |cn| if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn) command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1') begin def_system_command(command, sh.(cn)) rescue Shell.notify "warn: Can't define #{command} path: #{cn}" end defined_meth[command] = command end end end end
.method_added(id)
[ GitHub ]# File 'lib/shell/command-processor.rb', line 47
def self.method_added(id) add_delegate_command_to_shell(id) end
.run_config
include run file.
# File 'lib/shell/command-processor.rb', line 55
def self.run_config rc = "~/.rb_shell" begin load File.(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   
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   
Undefines a command
Instance Method Details
#[](command, file1, file2 = nil)
Alias for #test.
# File 'lib/shell/command-processor.rb', line 195
alias [] test
#append(to, filter)
[ GitHub ]#cat(*filename) ⇒ Cat
Returns a Cat object, for the given filenames
#check_point Also known as: #finish_all_jobs
# File 'lib/shell/command-processor.rb', line 263
def check_point # :nodoc: @shell.process_controller.wait_all_jobs_execution end
#concat(*jobs) ⇒ Concat
Returns a Concat object, for the given Shell#jobs
#echo(*strings) ⇒ Echo
Returns a Echo object, for the given strings
#expand_path(path)
#expand_path(path)
  path:   String
  return: String
returns the absolute path for <path># File 'lib/shell/command-processor.rb', line 80
def (path) @shell.(path) end
#find_system_command(command)
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
#finish_all_jobs
Alias for #check_point.
# File 'lib/shell/command-processor.rb', line 266
alias finish_all_jobs check_point # :nodoc:
    
      #foreach(path, record_separator)  ⇒ Enumerator 
      #foreach(path, record_separator)  
    
  
Enumerator 
      #foreach(path, record_separator)  
    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 = (path) if File.directory?(path) Dir.foreach(path){|fn| yield fn} else IO.foreach(path, *rs){|l| yield l} end end
#glob(pattern) ⇒ Glob
def sort(*filenames)
  Sort.new(self, *filenames)
endReturns a Glob filter object, with the given pattern object
#mkdir(path)
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 = (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)
%pwd, %cwd -> @pwd
    
      #open(path, mode, permissions)  ⇒ Enumerator 
      #open(path, mode, permissions)  
    
  
Enumerator 
      #open(path, mode, permissions)  
    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 = (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)
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
Clears the command hash table.
# File 'lib/shell/command-processor.rb', line 259
def rehash @system_commands = {} end
#rmdir(path)
Same as Dir.rmdir, except multiple directories are allowed.
#system(command, *options) ⇒ SystemCommand
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
Returns a Tee filter object, with the given file command
    
      #test(command, file1, file2)  ⇒ Boolean 
      #[](command, file1, file2)  ⇒ Boolean 
    
    Also known as: #[]
  
Boolean 
      #[](command, file1, file2)  ⇒ Boolean 
    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 = (file1) file2 = (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
#top_level_test
See #test
# File 'lib/shell/command-processor.rb', line 149
alias top_level_test test
#transact
# File 'lib/shell/command-processor.rb', line 275
def transact(&block) begin @shell.instance_eval(&block) ensure check_point end end
#unlink(path)
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 = (path) if File.directory?(path) Dir.unlink(path) else IO.unlink(path) end Void.new(@shell) end