класс Shell
Shell реализует удобный интерфейс Ruby для общих команд оболочки UNIX.
Он предоставляет пользователям возможность выполнять команды с фильтрами и каналами, например, sh/csh с использованием собственных возможностей Ruby.
Примеры
Создание временного файла
В этом примере мы создадим три tmpFile в трёх разных папках в каталоге /tmp.
sh = Shell.cd("/tmp") # Change to the /tmp directory
sh.mkdir "shell-test-1" unless sh.exists?("shell-test-1")
# make the 'shell-test-1' directory if it doesn't already exist
sh.cd("shell-test-1") # Change to the /tmp/shell-test-1 directory
for dir in ["dir1", "dir3", "dir5"]
if !sh.exists?(dir)
sh.mkdir dir # make dir if it doesn't already exist
sh.cd(dir) do
# change to the `dir` directory
f = sh.open("tmpFile", "w") # open a new file in write mode
f.print "TEST\n" # write to the file
f.close # close the file handler
end
print sh.pwd # output the process working directory
end
end
Создание временного файла с использованием self
Этот пример идентичен первому, за исключением использования Shell::CommandProcessor#transact.
Shell::CommandProcessor#transact выполняет заданный блок относительно self, в данном случае sh; нашего объекта Shell. Внутри блока мы можем заменить sh.cd на cd, поскольку область действия внутри блока уже использует sh.
sh = Shell.cd("/tmp")
sh.transact do
mkdir "shell-test-1" unless exists?("shell-test-1")
cd("shell-test-1")
for dir in ["dir1", "dir3", "dir5"]
if !exists?(dir)
mkdir dir
cd(dir) do
f = open("tmpFile", "w")
f.print "TEST\n"
f.close
end
print pwd
end
end
end
Перенаправление /etc/printcap в файл
В этом примере мы будем читать системный файл /etc/printcap, сгенерированный cupsd, и затем выводить его в новый файл, относящийся к каталогу pwd объекта sh.
sh = Shell.new
sh.cat("/etc/printcap") | sh.tee("tee1") > "tee2"
(sh.cat < "/etc/printcap") | sh.tee("tee11") > "tee12"
sh.cat("/etc/printcap") | sh.tee("tee1") >> "tee2"
(sh.cat < "/etc/printcap") | sh.tee("tee11") >> "tee12"
Атрибуты
Возвращает текущую рабочую директорию.
Возвращает текущую рабочую директорию.
Возвращает текущую рабочую директорию.
Возвращает текущую рабочую директорию.
Возвращает путь поиска команд в массиве
Возвращает значение umask
Методы публичного класса
# File lib/shell.rb, line 393 def Shell.alias_command(ali, command, *opts, &block) CommandProcessor.alias_command(ali, command, *opts, &block) end
Удобный метод для Shell::CommandProcessor.alias_command. Определяет метод экземпляра, который выполнит команду под альтернативным именем.
Shell.def_system_command('date')
Shell.alias_command('date_in_utc', 'date', '-u')
Shell.new.date_in_utc # => Sat Jan 25 16:59:57 UTC 2014
# File lib/shell.rb, line 125 def cd(path) new(path) end
Создаёт новый экземпляр Shell с текущей рабочей директорией, установленной в path.
# File lib/shell.rb, line 114 def debug=(val) @debug = val @verbose = val if val end
# File lib/shell.rb, line 373 def Shell.def_system_command(command, path = command) CommandProcessor.def_system_command(command, path) end
Удобный метод для Shell::CommandProcessor.def_system_command. Определяет метод экземпляра, который выполнит заданную командную строку. Если исполняемый файл не находится в ::default_system_path, вы должны указать путь к нему.
Shell.def_system_command('hostname')
Shell.new.hostname # => localhost
# How to use an executable that's not in the default path
Shell.def_system_command('run_my_program', "~/hello")
Shell.new.run_my_program # prints "Hello from a C program!"
# File lib/shell.rb, line 158
def default_record_separator
if @default_record_separator
@default_record_separator
else
$/
end
end # File lib/shell.rb, line 166 def default_record_separator=(rs) @default_record_separator = rs end
# File lib/shell.rb, line 142
def default_system_path
if @default_system_path
@default_system_path
else
ENV["PATH"].split(":")
end
end Возвращает директории из переменной окружения PATH текущей оболочки в виде массива имён директорий. Это устанавливает #system_path для всех экземпляров Shell.
Пример: Если в вашей текущей оболочке вы сделали:
$ echo $PATH /usr/bin:/bin:/usr/local/bin
Выполнение этого метода в вышеуказанной оболочке вернёт:
["/usr/bin", "/bin", "/usr/local/bin"]
# File lib/shell.rb, line 154 def default_system_path=(path) @default_system_path = path end
Устанавливает #system_path, который должны иметь новые экземпляры Shell в качестве их начального значения system_path.
path должен быть массивом строк имён директорий.
# File lib/shell.rb, line 413 def Shell.install_system_commands(pre = "sys_") CommandProcessor.install_system_commands(pre) end
Удобный метод для Shell::CommandProcessor.install_system_commands. Определяет методы экземпляров, представляющие все исполняемые файлы, найденные в ::default_system_path, с указанным префиксом, добавленным к их именам.
Shell.install_system_commands
Shell.new.sys_echo("hello") # => hello
# File lib/shell.rb, line 183 def initialize(pwd = Dir.pwd, umask = nil) @cwd = File.expand_path(pwd) @dir_stack = [] @umask = umask @system_path = Shell.default_system_path @record_separator = Shell.default_record_separator @command_processor = CommandProcessor.new(self) @process_controller = ProcessController.new(self) @verbose = Shell.verbose @debug = Shell.debug end
Создаёт объект Shell, текущей директорией которого является текущая директория процесса, если не указано иное аргументом pwd.
# File lib/shell.rb, line 426
def self.notify(*opts)
Shell::debug_output_synchronize do
if opts[-1].kind_of?(String)
yorn = verbose?
else
yorn = opts.pop
end
return unless yorn
if @debug_display_thread_id
if @debug_display_process_id
prefix = "shell(##{Process.pid}:#{Thread.current.to_s.sub("Thread", "Th")}): "
else
prefix = "shell(#{Thread.current.to_s.sub("Thread", "Th")}): "
end
else
prefix = "shell: "
end
_head = true
STDERR.print opts.collect{|mes|
mes = mes.dup
yield mes if iterator?
if _head
_head = false
prefix + mes
else
" "* prefix.size + mes
end
}.join("\n")+"\n"
end
end # File lib/shell.rb, line 398 def Shell.unalias_command(ali) CommandProcessor.unalias_command(ali) end
Удобный метод для Shell::CommandProcessor.unalias_command
# File lib/shell.rb, line 378 def Shell.undef_system_command(command) CommandProcessor.undef_system_command(command) end
Удобный метод для Shell::CommandProcessor.undef_system_command
Публичные методы экземпляров
# File lib/shell.rb, line 261
def chdir(path = nil, verbose = @verbose)
check_point
if iterator?
notify("chdir(with block) #{path}") if verbose
cwd_old = @cwd
begin
chdir(path, nil)
yield
ensure
chdir(cwd_old, nil)
end
else
notify("chdir #{path}") if verbose
path = "~" unless path
@cwd = expand_path(path)
notify "current dir: #{@cwd}"
rehash
Void.new(self)
end
end Создаёт объект Shell, текущий каталог которого установлен на path.
Если задан блок кода, текущий каталог восстанавливается по окончании блока.
Если вызывается как итератор, текущий каталог восстанавливается по окончании блока.
# File lib/shell.rb, line 216 def debug=(val) @debug = val @verbose = val if val end
# File lib/shell.rb, line 227 def expand_path(path) File.expand_path(path, @cwd) end
# File lib/shell.rb, line 418
def inspect
if debug.kind_of?(Integer) && debug > 2
super
else
to_s
end
end # File lib/shell.rb, line 345 def jobs @process_controller.jobs end
Возвращает список запланированных задач.
# File lib/shell.rb, line 353 def kill(sig, command) @process_controller.kill_job(sig, command) end
Отправляет заданный signal заданному job
# File lib/shell.rb, line 329
def popdir
check_point
notify("popdir")
if pop = @dir_stack.pop
chdir pop
notify "dir stack: [#{@dir_stack.join ', '}]"
self
else
Shell.Fail DirStackEmpty
end
Void.new(self)
end Извлекает каталог из стека каталогов и устанавливает текущий каталог на него.
# File lib/shell.rb, line 295
def pushdir(path = nil, verbose = @verbose)
check_point
if iterator?
notify("pushdir(with block) #{path}") if verbose
pushdir(path, nil)
begin
yield
ensure
popdir
end
elsif path
notify("pushdir #{path}") if verbose
@dir_stack.push @cwd
chdir(path, nil)
notify "dir stack: [#{@dir_stack.join ', '}]"
self
else
notify("pushdir") if verbose
if pop = @dir_stack.pop
@dir_stack.push @cwd
chdir pop
notify "dir stack: [#{@dir_stack.join ', '}]"
self
else
Shell.Fail DirStackEmpty
end
end
Void.new(self)
end Добавляет текущий каталог в стек каталогов, изменяя текущий каталог на path.
Если path опущено, происходит обмен текущим каталогом и вершиной стека каталогов.
Если задан блок, текущий каталог восстанавливается по завершении блока.
# File lib/shell.rb, line 204 def system_path=(path) @system_path = path rehash end
Устанавливает системный путь (переменную окружения PATH экземпляра Shell).
path должен быть массивом строк имён каталогов.
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.