Class Shell::CommandProcessor
In: lib/shell/command-processor.rb
Parent: Object

Methods

Constants

NoDelegateMethods = ["initialize", "expand_path"]   initialize of Shell and related classes.

External Aliases

test -> top_level_test
  CommandProcessor#test(command, file1, file2) CommandProcessor#[command, file1, file2]
    command: char or String or Symbol
    file1:   String
    file2:   String(optional)
    return: Boolean
  same as:
    test()     (when command is char or length 1 string or symbol)
    FileTest.command (others)
  example:
    sh[?e, "foo"]
    sh[:e, "foo"]
    sh["e", "foo"]
    sh[:exists?, "foo"]
    sh["exists?", "foo"]

Public Class methods

[Source]

     # File lib/shell/command-processor.rb, line 505
505:     def self.add_delegate_command_to_shell(id)
506:       id = id.intern if id.kind_of?(String)
507:       name = id.id2name
508:       if Shell.method_defined?(id)
509:         Shell.notify "warn: override definnition of Shell##{name}."
510:         Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
511:         Shell.module_eval "alias #{name}_org #{name}"
512:       end
513:       Shell.notify "method added: Shell##{name}.", Shell.debug?
514:       Shell.module_eval(%Q[def #{name}(*args, &block)
515:                             begin
516:                               @command_processor.__send__(:#{name}, *args, &block)
517:                             rescue Exception
518:                               $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
519:                               $@.delete_if{|s| /^\\(eval\\):/ =~ s}
520:                             raise
521:                             end
522:                           end], __FILE__, __LINE__)
523: 
524:       if Shell::Filter.method_defined?(id)
525:         Shell.notify "warn: override definnition of Shell::Filter##{name}."
526:         Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
527:         Filter.module_eval "alias #{name}_org #{name}"
528:       end
529:       Shell.notify "method added: Shell::Filter##{name}.", Shell.debug?
530:       Filter.module_eval(%Q[def #{name}(*args, &block)
531:                             begin
532:                               self | @shell.__send__(:#{name}, *args, &block)
533:                             rescue Exception
534:                               $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
535:                               $@.delete_if{|s| /^\\(eval\\):/ =~ s}
536:                             raise
537:                             end
538:                           end], __FILE__, __LINE__)
539:     end

[Source]

     # File lib/shell/command-processor.rb, line 396
396:     def self.alias_command(ali, command, *opts, &block)
397:       ali = ali.id2name if ali.kind_of?(Symbol)
398:       command = command.id2name if command.kind_of?(Symbol)
399:       begin
400:         if iterator?
401:           @alias_map[ali.intern] = proc
402: 
403:           eval((d = %Q[def #{ali}(*opts)
404:                           @shell.__send__(:#{command},
405:                                           *(CommandProcessor.alias_map[:#{ali}].call *opts))
406:                         end]), nil, __FILE__, __LINE__ - 1)
407:     
408:         else
409:            args = opts.collect{|opt| '"' + opt + '"'}.join(",")
410:            eval((d = %Q[def #{ali}(*opts)
411:                           @shell.__send__(:#{command}, #{args}, *opts)
412:                         end]), nil, __FILE__, __LINE__ - 1)
413:         end
414:       rescue SyntaxError
415:         Shell.notify "warn: Can't alias #{ali} command: #{command}." 
416:         Shell.notify("Definition of #{ali}: ", d)
417:         raise
418:       end
419:       Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
420:       Shell.notify("Definition of #{ali}: ", d, 
421:              Shell.debug.kind_of?(Integer) && Shell.debug > 1)
422:       self
423:     end

[Source]

     # File lib/shell/command-processor.rb, line 393
393:     def self.alias_map
394:       @alias_map
395:     end

CommandProcessor.def_builtin_commands(delegation_class, command_specs)

    delegation_class: Class or Module
    command_specs: [[command_name, [argument,...]],...]
       command_name: String
       arguments:      String
          FILENAME?? -> expand_path(filename??)
          *FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(", ")
  define command_name(argument,...) as
      delegation_class.command_name(argument,...)

[Source]

     # File lib/shell/command-processor.rb, line 442
442:     def self.def_builtin_commands(delegation_class, command_specs)
443:       for meth, args in command_specs
444:         arg_str = args.collect{|arg| arg.downcase}.join(", ")
445:         call_arg_str = args.collect{
446:           |arg|
447:           case arg
448:           when /^(FILENAME.*)$/
449:             format("expand_path(%s)", $1.downcase)
450:           when /^(\*FILENAME.*)$/
451:             # \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ")
452:             $1.downcase + '.collect{|fn| expand_path(fn)}'
453:           else
454:             arg
455:           end
456:         }.join(", ")
457:         d = %Q[def #{meth}(#{arg_str})
458:                     #{delegation_class}.#{meth}(#{call_arg_str})
459:                  end]
460:         Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
461:         Shell.notify("Definition of #{meth}: ", d, 
462:              Shell.debug.kind_of?(Integer) && Shell.debug > 1)
463:         eval d
464:       end
465:     end

CommandProcessor.def_system_command(command, path)

    command:  String
    path:       String
  define 'command()' method as method.

[Source]

     # File lib/shell/command-processor.rb, line 366
366:     def self.def_system_command(command, path = command)
367:       begin
368:         eval((d = %Q[def #{command}(*opts)
369:                   SystemCommand.new(@shell, '#{path}', *opts)
370:                end]), nil, __FILE__, __LINE__ - 1)
371:       rescue SyntaxError
372:         Shell.notify "warn: Can't define #{command} path: #{path}." 
373:       end
374:       Shell.notify "Define #{command} path: #{path}.", Shell.debug?
375:       Shell.notify("Definition of #{command}: ", d, 
376:              Shell.debug.kind_of?(Integer) && Shell.debug > 1)
377:     end

[Source]

    # File lib/shell/command-processor.rb, line 30
30:     def self.initialize
31: 
32:       install_builtin_commands
33: 
34:       # define CommandProccessor#methods to Shell#methods and Filter#methods
35:       for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
36:         add_delegate_command_to_shell(m)
37:       end
38:       
39:       def self.method_added(id)
40:         add_delegate_command_to_shell(id)
41:       end
42:     end

define default builtin commands

[Source]

     # File lib/shell/command-processor.rb, line 544
544:     def self.install_builtin_commands
545:       # method related File.
546:       # (exclude open/foreach/unlink)
547:       normal_delegation_file_methods = [
548:         ["atime", ["FILENAME"]],
549:         ["basename", ["fn", "*opts"]],
550:         ["chmod", ["mode", "*FILENAMES"]], 
551:         ["chown", ["owner", "group", "*FILENAME"]],
552:         ["ctime", ["FILENAMES"]],
553:         ["delete", ["*FILENAMES"]],
554:         ["dirname", ["FILENAME"]],
555:         ["ftype", ["FILENAME"]],
556:         ["join", ["*items"]],
557:         ["link", ["FILENAME_O", "FILENAME_N"]],
558:         ["lstat", ["FILENAME"]],
559:         ["mtime", ["FILENAME"]],
560:         ["readlink", ["FILENAME"]],
561:         ["rename", ["FILENAME_FROM", "FILENAME_TO"]],
562:         #      ["size", ["FILENAME"]],
563:         ["split", ["pathname"]],
564:         ["stat", ["FILENAME"]],
565:         ["symlink", ["FILENAME_O", "FILENAME_N"]],
566:         ["truncate", ["FILENAME", "length"]],
567:         ["utime", ["atime", "mtime", "*FILENAMES"]]]
568: 
569:       def_builtin_commands(File, normal_delegation_file_methods)
570:       alias_method :rm, :delete
571: 
572:       # method related FileTest
573:       def_builtin_commands(FileTest, 
574:                    FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})
575: 
576:       # method related ftools
577:       normal_delegation_ftools_methods = [
578:         ["syscopy", ["FILENAME_FROM", "FILENAME_TO"]],
579:         ["copy", ["FILENAME_FROM", "FILENAME_TO"]],
580:         ["move", ["FILENAME_FROM", "FILENAME_TO"]],
581:         ["compare", ["FILENAME_FROM", "FILENAME_TO"]],
582:         ["safe_unlink", ["*FILENAMES"]],
583:         ["makedirs", ["*FILENAMES"]],
584:         #    ["chmod", ["mode", "*FILENAMES"]],
585:         ["install", ["FILENAME_FROM", "FILENAME_TO", "mode"]],
586:       ]
587:       def_builtin_commands(File,
588:                    normal_delegation_ftools_methods)
589:       alias_method :cmp, :compare
590:       alias_method :mv, :move
591:       alias_method :cp, :copy
592:       alias_method :rm_f, :safe_unlink
593:       alias_method :mkpath, :makedirs
594:     end

CommandProcessor.install_system_commands(pre)

      pre: String - command name prefix

defines every command which belongs in default_system_path via CommandProcessor.command(). It doesn‘t define already defined methods twice. By default, "pre_" is prefixes to each method name. Characters that may not be used in a method name are all converted to ‘_’. Definition errors are just ignored.

[Source]

     # File lib/shell/command-processor.rb, line 476
476:     def self.install_system_commands(pre = "sys_")
477:       defined_meth = {}
478:       for m in Shell.methods
479:         defined_meth[m] = true
480:       end
481:       sh = Shell.new
482:       for path in Shell.default_system_path
483:         next unless sh.directory? path
484:         sh.cd path
485:         sh.foreach do
486:           |cn|
487:           if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)
488:             command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1')
489:             begin
490:               def_system_command(command, sh.expand_path(cn))
491:             rescue
492:               Shell.notify "warn: Can't define #{command} path: #{cn}"
493:             end
494:             defined_meth[command] = command
495:           end
496:         end
497:       end
498:     end

[Source]

    # File lib/shell/command-processor.rb, line 39
39:       def self.method_added(id)
40:         add_delegate_command_to_shell(id)
41:       end

[Source]

    # File lib/shell/command-processor.rb, line 60
60:     def initialize(shell)
61:       @shell = shell
62:       @system_commands = {}
63:     end

include run file.

[Source]

    # File lib/shell/command-processor.rb, line 47
47:     def self.run_config
48:       begin
49:         load File.expand_path("~/.rb_shell") if ENV.key?("HOME")
50:       rescue LoadError, Errno::ENOENT
51:       rescue
52:         print "load error: #{rc}\n"
53:         print $!.class, ": ", $!, "\n"
54:         for err in $@[0, $@.size - 2]
55:           print "\t", err, "\n"
56:         end
57:       end
58:     end

[Source]

     # File lib/shell/command-processor.rb, line 425
425:     def self.unalias_command(ali)
426:       ali = ali.id2name if ali.kind_of?(Symbol)
427:       @alias_map.delete ali.intern
428:       undef_system_command(ali)
429:     end

[Source]

     # File lib/shell/command-processor.rb, line 379
379:     def self.undef_system_command(command)
380:       command = command.id2name if command.kind_of?(Symbol)
381:       remove_method(command)
382:       Shell.module_eval{remove_method(command)}
383:       Filter.module_eval{remove_method(command)}
384:       self
385:     end

Public Instance methods

[](command, file1, file2=nil)

Alias for test

[Source]

     # File lib/shell/command-processor.rb, line 286
286:     def append(to, filter)
287:       case to
288:       when String
289:         AppendFile.new(@shell, to, filter)
290:       when IO
291:         AppendIO.new(@shell, to, filter)
292:       else
293:         Shell.Fail Error::CantApplyMethod, "append", to.class
294:       end
295:     end

[Source]

     # File lib/shell/command-processor.rb, line 274
274:     def cat(*filenames)
275:       Cat.new(@shell, *filenames)
276:     end

ProcessCommand#transact

[Source]

     # File lib/shell/command-processor.rb, line 250
250:     def check_point
251:       @shell.process_controller.wait_all_jobs_execution
252:     end

[Source]

     # File lib/shell/command-processor.rb, line 301
301:     def concat(*jobs)
302:       Concat.new(@shell, *jobs)
303:     end

[Source]

     # File lib/shell/command-processor.rb, line 270
270:     def echo(*strings)
271:       Echo.new(@shell, *strings)
272:     end

CommandProcessor#expand_path(path)

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

[Source]

    # File lib/shell/command-processor.rb, line 71
71:     def expand_path(path)
72:       @shell.expand_path(path)
73:     end

[Source]

     # File lib/shell/command-processor.rb, line 336
336:     def find_system_command(command)
337:       return command if /^\// =~ command
338:       case path = @system_commands[command]
339:       when String
340:         if exists?(path)
341:           return path
342:         else
343:           Shell.Fail Error::CommandNotFound, command
344:         end
345:       when false
346:         Shell.Fail Error::CommandNotFound, command
347:       end
348: 
349:       for p in @shell.system_path
350:         path = join(p, command)
351:         if FileTest.exists?(path)
352:           @system_commands[command] = path
353:           return path
354:         end
355:       end
356:       @system_commands[command] = false
357:       Shell.Fail Error::CommandNotFound, command
358:     end
finish_all_jobs()

Alias for check_point

File related commands Shell#foreach Shell#open Shell#unlink Shell#test

-

CommandProcessor#foreach(path, rs)

    path: String
    rs:     String - record separator
    iterator
  Same as:
    File#foreach (when path is file)
    Dir#foreach (when path is directory)
  path is relative to pwd

[Source]

     # File lib/shell/command-processor.rb, line 93
 93:     def foreach(path = nil, *rs)
 94:       path = "." unless path
 95:       path = expand_path(path)
 96: 
 97:       if File.directory?(path)
 98:         Dir.foreach(path){|fn| yield fn}
 99:       else
100:         IO.foreach(path, *rs){|l| yield l}
101:       end
102:     end

def sort(*filenames)

  Sort.new(self, *filenames)

end

[Source]

     # File lib/shell/command-processor.rb, line 282
282:     def glob(pattern)
283:       Glob.new(@shell, pattern)
284:     end

Dir related methods

Shell#mkdir Shell#rmdir

[Source]

     # File lib/shell/command-processor.rb, line 201
201:     def mkdir(*path)
202:       for dir in path
203:         Dir.mkdir(expand_path(dir))
204:       end
205:     end

%pwd, %cwd -> @pwd

[Source]

     # File lib/shell/command-processor.rb, line 306
306:     def notify(*opts, &block)
307:       Thread.exclusive do
308:         Shell.notify(*opts) {|mes|
309:           yield mes if iterator?
310:         
311:           mes.gsub!("%pwd", "#{@cwd}")
312:           mes.gsub!("%cwd", "#{@cwd}")
313:         }
314:       end
315:     end

CommandProcessor#open(path, mode)

    path:     String
    mode:     String
    return: File or Dir
  Same as:
    File#open (when path is file)
    Dir#open  (when path is directory)
  mode has an effect only when path is a file

[Source]

     # File lib/shell/command-processor.rb, line 114
114:     def open(path, mode)
115:       path = expand_path(path)
116:       if File.directory?(path)
117:         Dir.open(path)
118:       else
119:         effect_umask do
120:           File.open(path, mode)
121:         end
122:       end
123:     end

internal commands

[Source]

     # File lib/shell/command-processor.rb, line 266
266:     def out(dev = STDOUT, &block)
267:       dev.print transact(&block)
268:     end

ProcessCommand#rehash

  clear command hash table.

[Source]

     # File lib/shell/command-processor.rb, line 243
243:     def rehash
244:       @system_commands = {}
245:     end

CommandProcessor#rmdir(*path)

    path: String
  same as Dir.rmdir()

[Source]

     # File lib/shell/command-processor.rb, line 212
212:     def rmdir(*path)
213:       for dir in path
214:         Dir.rmdir(expand_path(dir))
215:       end
216:     end

CommandProcessor#system(command, *opts)

    command: String
    opts:      String
    return:  SystemCommand
  Same as system() function
  example:
    print sh.system("ls", "-l")
    sh.system("ls", "-l") | sh.head > STDOUT

[Source]

     # File lib/shell/command-processor.rb, line 228
228:     def system(command, *opts)
229:       if opts.empty?
230:         if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
231:           return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
232:         else
233:           command, *opts = command.split(/\s+/)
234:         end
235:       end
236:       SystemCommand.new(@shell, find_system_command(command), *opts)
237:     end

[Source]

     # File lib/shell/command-processor.rb, line 297
297:     def tee(file)
298:       Tee.new(@shell, file)
299:     end

[Source]

     # File lib/shell/command-processor.rb, line 159
159:     def test(command, file1, file2=nil)
160:       file1 = expand_path(file1)
161:       file2 = expand_path(file2) if file2
162:       command = command.id2name if command.kind_of?(Symbol)
163: 
164:       case command
165:       when Integer
166:         if file2
167:           top_level_test(command, file1, file2)
168:         else
169:           top_level_test(command, file1)
170:         end
171:       when String
172:         if command.size == 1
173:           if file2
174:             top_level_test(command, file1, file2)
175:           else
176:             top_level_test(command, file1)
177:           end
178:         else
179:           if file2
180:             FileTest.send(command, file1, file2)
181:           else
182:             FileTest.send(command, file1)
183:           end
184:         end
185:       end
186:     end

[Source]

     # File lib/shell/command-processor.rb, line 255
255:     def transact(&block)
256:       begin
257:         @shell.instance_eval(&block)
258:       ensure
259:         check_point
260:       end
261:     end

CommandProcessor#unlink(path)

  same as:
    Dir#unlink  (when path is directory)
    File#unlink (when path is file)

[Source]

     # File lib/shell/command-processor.rb, line 132
132:     def unlink(path)
133:       path = expand_path(path)
134:       if File.directory?(path)
135:         Dir.unlink(path)
136:       else
137:         IO.unlink(path)
138:       end
139:     end

Private Instance methods

private functions

[Source]

     # File lib/shell/command-processor.rb, line 320
320:     def effect_umask
321:       if @shell.umask
322:         Thread.critical = true
323:         save = File.umask
324:         begin
325:           yield
326:         ensure
327:           File.umask save
328:           Thread.critical = false
329:         end
330:       else
331:         yield
332:       end
333:     end

[Validate]