| Class | Shell::CommandProcessor |
| In: |
lib/shell/command-processor.rb
|
| Parent: | Object |
| NoDelegateMethods | = | ["initialize", "expand_path"] | initialize of Shell and related classes. |
# File lib/shell/command-processor.rb, line 500
500: def self.add_delegate_command_to_shell(id)
501: id = id.intern if id.kind_of?(String)
502: name = id.id2name
503: if Shell.method_defined?(id)
504: Shell.notify "warn: override definnition of Shell##{name}."
505: Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
506: Shell.module_eval "alias #{name}_org #{name}"
507: end
508: Shell.notify "method added: Shell##{name}.", Shell.debug?
509: Shell.module_eval(%Q[def #{name}(*args, &block)
510: begin
511: @command_processor.__send__(:#{name}, *args, &block)
512: rescue Exception
513: $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
514: $@.delete_if{|s| /^\\(eval\\):/ =~ s}
515: raise
516: end
517: end], __FILE__, __LINE__)
518:
519: if Shell::Filter.method_defined?(id)
520: Shell.notify "warn: override definnition of Shell::Filter##{name}."
521: Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
522: Filter.module_eval "alias #{name}_org #{name}"
523: end
524: Shell.notify "method added: Shell::Filter##{name}.", Shell.debug?
525: Filter.module_eval(%Q[def #{name}(*args, &block)
526: begin
527: self | @shell.__send__(:#{name}, *args, &block)
528: rescue Exception
529: $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
530: $@.delete_if{|s| /^\\(eval\\):/ =~ s}
531: raise
532: end
533: end], __FILE__, __LINE__)
534: end
# File lib/shell/command-processor.rb, line 391
391: def self.alias_command(ali, command, *opts, &block)
392: ali = ali.id2name if ali.kind_of?(Symbol)
393: command = command.id2name if command.kind_of?(Symbol)
394: begin
395: if iterator?
396: @alias_map[ali.intern] = proc
397:
398: eval((d = %Q[def #{ali}(*opts)
399: @shell.__send__(:#{command},
400: *(CommandProcessor.alias_map[:#{ali}].call *opts))
401: end]), nil, __FILE__, __LINE__ - 1)
402:
403: else
404: args = opts.collect{|opt| '"' + opt + '"'}.join(",")
405: eval((d = %Q[def #{ali}(*opts)
406: @shell.__send__(:#{command}, #{args}, *opts)
407: end]), nil, __FILE__, __LINE__ - 1)
408: end
409: rescue SyntaxError
410: Shell.notify "warn: Can't alias #{ali} command: #{command}."
411: Shell.notify("Definition of #{ali}: ", d)
412: raise
413: end
414: Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
415: Shell.notify("Definition of #{ali}: ", d,
416: Shell.debug.kind_of?(Integer) && Shell.debug > 1)
417: self
418: 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,...)
# File lib/shell/command-processor.rb, line 437
437: def self.def_builtin_commands(delegation_class, command_specs)
438: for meth, args in command_specs
439: arg_str = args.collect{|arg| arg.downcase}.join(", ")
440: call_arg_str = args.collect{
441: |arg|
442: case arg
443: when /^(FILENAME.*)$/
444: format("expand_path(%s)", $1.downcase)
445: when /^(\*FILENAME.*)$/
446: # \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ")
447: $1.downcase + '.collect{|fn| expand_path(fn)}'
448: else
449: arg
450: end
451: }.join(", ")
452: d = %Q[def #{meth}(#{arg_str})
453: #{delegation_class}.#{meth}(#{call_arg_str})
454: end]
455: Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
456: Shell.notify("Definition of #{meth}: ", d,
457: Shell.debug.kind_of?(Integer) && Shell.debug > 1)
458: eval d
459: end
460: end
CommandProcessor.def_system_command(command, path)
command: String
path: String
define 'command()' method as method.
# File lib/shell/command-processor.rb, line 361
361: def self.def_system_command(command, path = command)
362: begin
363: eval((d = %Q[def #{command}(*opts)
364: SystemCommand.new(@shell, '#{path}', *opts)
365: end]), nil, __FILE__, __LINE__ - 1)
366: rescue SyntaxError
367: Shell.notify "warn: Can't define #{command} path: #{path}."
368: end
369: Shell.notify "Define #{command} path: #{path}.", Shell.debug?
370: Shell.notify("Definition of #{command}: ", d,
371: Shell.debug.kind_of?(Integer) && Shell.debug > 1)
372: end
# 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
# File lib/shell/command-processor.rb, line 539
539: def self.install_builtin_commands
540: # method related File.
541: # (exclude open/foreach/unlink)
542: normal_delegation_file_methods = [
543: ["atime", ["FILENAME"]],
544: ["basename", ["fn", "*opts"]],
545: ["chmod", ["mode", "*FILENAMES"]],
546: ["chown", ["owner", "group", "*FILENAME"]],
547: ["ctime", ["FILENAMES"]],
548: ["delete", ["*FILENAMES"]],
549: ["dirname", ["FILENAME"]],
550: ["ftype", ["FILENAME"]],
551: ["join", ["*items"]],
552: ["link", ["FILENAME_O", "FILENAME_N"]],
553: ["lstat", ["FILENAME"]],
554: ["mtime", ["FILENAME"]],
555: ["readlink", ["FILENAME"]],
556: ["rename", ["FILENAME_FROM", "FILENAME_TO"]],
557: # ["size", ["FILENAME"]],
558: ["split", ["pathname"]],
559: ["stat", ["FILENAME"]],
560: ["symlink", ["FILENAME_O", "FILENAME_N"]],
561: ["truncate", ["FILENAME", "length"]],
562: ["utime", ["atime", "mtime", "*FILENAMES"]]]
563:
564: def_builtin_commands(File, normal_delegation_file_methods)
565: alias_method :rm, :delete
566:
567: # method related FileTest
568: def_builtin_commands(FileTest,
569: FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})
570:
571: # method related ftools
572: normal_delegation_ftools_methods = [
573: ["syscopy", ["FILENAME_FROM", "FILENAME_TO"]],
574: ["copy", ["FILENAME_FROM", "FILENAME_TO"]],
575: ["move", ["FILENAME_FROM", "FILENAME_TO"]],
576: ["compare", ["FILENAME_FROM", "FILENAME_TO"]],
577: ["safe_unlink", ["*FILENAMES"]],
578: ["makedirs", ["*FILENAMES"]],
579: # ["chmod", ["mode", "*FILENAMES"]],
580: ["install", ["FILENAME_FROM", "FILENAME_TO", "mode"]],
581: ]
582: def_builtin_commands(File,
583: normal_delegation_ftools_methods)
584: alias_method :cmp, :compare
585: alias_method :mv, :move
586: alias_method :cp, :copy
587: alias_method :rm_f, :safe_unlink
588: alias_method :mkpath, :makedirs
589: 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.
# File lib/shell/command-processor.rb, line 471
471: def self.install_system_commands(pre = "sys_")
472: defined_meth = {}
473: for m in Shell.methods
474: defined_meth[m] = true
475: end
476: sh = Shell.new
477: for path in Shell.default_system_path
478: next unless sh.directory? path
479: sh.cd path
480: sh.foreach do
481: |cn|
482: if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)
483: command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1')
484: begin
485: def_system_command(command, sh.expand_path(cn))
486: rescue
487: Shell.notify "warn: Can't define #{command} path: #{cn}"
488: end
489: defined_meth[command] = command
490: end
491: end
492: end
493: end
# File lib/shell/command-processor.rb, line 39
39: def self.method_added(id)
40: add_delegate_command_to_shell(id)
41: end
# File lib/shell/command-processor.rb, line 60
60: def initialize(shell)
61: @shell = shell
62: @system_commands = {}
63: end
include run file.
# 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
# File lib/shell/command-processor.rb, line 420
420: def self.unalias_command(ali)
421: ali = ali.id2name if ali.kind_of?(Symbol)
422: @alias_map.delete ali.intern
423: undef_system_command(ali)
424: end
# File lib/shell/command-processor.rb, line 374
374: def self.undef_system_command(command)
375: command = command.id2name if command.kind_of?(Symbol)
376: remove_method(command)
377: Shell.module_eval{remove_method(command)}
378: Filter.module_eval{remove_method(command)}
379: self
380: end
# File lib/shell/command-processor.rb, line 281
281: def append(to, filter)
282: case to
283: when String
284: AppendFile.new(@shell, to, filter)
285: when IO
286: AppendIO.new(@shell, to, filter)
287: else
288: Shell.Fail Error::CantApplyMethod, "append", to.class
289: end
290: end
# File lib/shell/command-processor.rb, line 269
269: def cat(*filenames)
270: Cat.new(@shell, *filenames)
271: end
ProcessCommand#transact
# File lib/shell/command-processor.rb, line 245
245: def check_point
246: @shell.process_controller.wait_all_jobs_execution
247: end
# File lib/shell/command-processor.rb, line 296
296: def concat(*jobs)
297: Concat.new(@shell, *jobs)
298: end
# File lib/shell/command-processor.rb, line 265
265: def echo(*strings)
266: Echo.new(@shell, *strings)
267: end
CommandProcessor#expand_path(path)
path: String
return: String
returns the absolute path for <path>
# File lib/shell/command-processor.rb, line 71
71: def expand_path(path)
72: @shell.expand_path(path)
73: end
# File lib/shell/command-processor.rb, line 331
331: def find_system_command(command)
332: return command if /^\// =~ command
333: case path = @system_commands[command]
334: when String
335: if exists?(path)
336: return path
337: else
338: Shell.Fail Error::CommandNotFound, command
339: end
340: when false
341: Shell.Fail Error::CommandNotFound, command
342: end
343:
344: for p in @shell.system_path
345: path = join(p, command)
346: if FileTest.exists?(path)
347: @system_commands[command] = path
348: return path
349: end
350: end
351: @system_commands[command] = false
352: Shell.Fail Error::CommandNotFound, command
353: end
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
# 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
# File lib/shell/command-processor.rb, line 277
277: def glob(pattern)
278: Glob.new(@shell, pattern)
279: end
%pwd, %cwd -> @pwd
# File lib/shell/command-processor.rb, line 301
301: def notify(*opts, &block)
302: Thread.exclusive do
303: Shell.notify(*opts) {|mes|
304: yield mes if iterator?
305:
306: mes.gsub!("%pwd", "#{@cwd}")
307: mes.gsub!("%cwd", "#{@cwd}")
308: }
309: end
310: 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
# 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
# File lib/shell/command-processor.rb, line 261
261: def out(dev = STDOUT, &block)
262: dev.print transact(&block)
263: end
ProcessCommand#rehash
clear command hash table.
# File lib/shell/command-processor.rb, line 238
238: def rehash
239: @system_commands = {}
240: end
path: String
same as Dir.rmdir()
# File lib/shell/command-processor.rb, line 207
207: def rmdir(*path)
208: for dir in path
209: Dir.rmdir(expand_path(dir))
210: end
211: 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
# File lib/shell/command-processor.rb, line 223
223: def system(command, *opts)
224: if opts.empty?
225: if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
226: return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
227: else
228: command, *opts = command.split(/\s+/)
229: end
230: end
231: SystemCommand.new(@shell, find_system_command(command), *opts)
232: end
# File lib/shell/command-processor.rb, line 292
292: def tee(file)
293: Tee.new(@shell, file)
294: end
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"]
# File lib/shell/command-processor.rb, line 158
158: def test(command, file1, file2=nil)
159: file1 = expand_path(file1)
160: file2 = expand_path(file2) if file2
161: command = command.id2name if command.kind_of?(Symbol)
162:
163: case command
164: when Integer
165: top_level_test(command, file1, file2)
166: when String
167: if command.size == 1
168: if file2
169: top_level_test(command, file1, file2)
170: else
171: top_level_test(command, file1)
172: end
173: else
174: if file2
175: FileTest.send(command, file1, file2)
176: else
177: FileTest.send(command, file1)
178: end
179: end
180: end
181: end
# File lib/shell/command-processor.rb, line 250
250: def transact(&block)
251: begin
252: @shell.instance_eval(&block)
253: ensure
254: check_point
255: end
256: end
same as:
Dir#unlink (when path is directory)
File#unlink (when path is file)
# 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