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
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
Returns a list of aliased commands
# File lib/shell/command-processor.rb, line 427 def self.alias_map @alias_map end
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
# 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
# File lib/shell/command-processor.rb, line 47 def self.method_added(id) add_delegate_command_to_shell(id) end
# File lib/shell/command-processor.rb, line 69 def initialize(shell) @shell = shell @system_commands = {} end
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
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
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
# 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
Returns a Cat
object, for the given filenames
# File lib/shell/command-processor.rb, line 304 def cat(*filenames) Cat.new(@shell, *filenames) end
Returns a Concat
object, for the given jobs
# File lib/shell/command-processor.rb, line 342 def concat(*jobs) Concat.new(@shell, *jobs) end
Returns a Echo
object, for the given strings
# File lib/shell/command-processor.rb, line 296 def echo(*strings) Echo.new(@shell, *strings) end
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
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
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
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
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
%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
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
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
Clears the command hash table.
# File lib/shell/command-processor.rb, line 259 def rehash @system_commands = {} end
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
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
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
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
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
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