Это послужило основанием для создания библиотеки Shell, которая упрощает, к примеру, организацию конвейеров команд и перенаправление вывода в файл. Кроме того, она сводит воедино функциональность из разных источников, скрывая ее за интерфейсом объекта Shell. (На платформе Windows эта библиотека работает не во всех случаях.)

14.3.1. Использование библиотеки Shell для перенаправления ввода/вывода

В классе Shell для создания объектов есть два метода: new и cd. Первый создает объект, ассоциированный с текущим каталогом, второй — объект, для которого рабочим будет указанный каталог.

require 'shell'

sh1 = Shell.new            # Работать в текущем каталоге.

sh2 = Shell.cd('/tmp/hal') # Работать в каталоге /tmp/hal.

Библиотека Shell определяет несколько встроенных команд (например, echo, cat и tee) в виде методов. Они всегда возвращают объекты класса Filter (как и определяемые пользователем команды, с которыми мы вскоре познакомимся).

Класс Filter понимает, что такое перенаправление ввода/вывода. В нем определены методы (или операторы) <, > и |, которые ведут себя примерно так, как мы ожидаем по многолетнему опыту написания shell-сценариев.

Если методу перенаправления передать в качестве параметра строку, то она будет считаться именем файла. Если же параметром является объект IO, он используется для операций ввода/вывода. Примеры:

sh = Shell.new

# Вывести файл motd на stdout.

sh.cat('/etc/motd') > STDOUT

# Напечатать его еще раз.

(sh.cat < '/etc/motd') > STDOUT

(sh.echo 'Это тест') > 'myfile.txt'

# Добавить строку в конец файла /etc/motd.

sh.echo('Hello, world!') >> '/etc/motd'

# Вывести два файла на stdout и продублировать (tee) вывод в третий файл.

(sh.cat 'file1' 'file2') | (tee 'file3') > STDOUT

Отметим, что у оператора > высокий приоритет. Скобки, которые вы видите в данном примере, в большинстве случаев обязательны. Вот два примера правильного использования и один — неправильного:

# Интерпретатор Ruby понимает такую конструкцию...

sh.cat('myfile.txt') > STDOUT

# ...и такую тоже.

(sh.cat 'myfile.txt') > STDOUT

# TypeError! (ошибка связана с приоритетами).

sh.cat 'myfile.txt' > STDOUT

Отметим еще, что можно «инсталлировать» системные команды по своему выбору. Для этого служит метод def_system_command. Ниже определяются два метода: ls и ll, которые выводят список файлов в текущем каталоге (в коротком и длинном формате).

# Имя метода совпадает с именем команды...

# Необходим только один параметр:

Shell.def_system_command 'ls'

# А здесь должно быть два параметра:

Shell.def_system_command 'll', 'ls -l'

sh = Shell.new

sh.ls > STDOUT # Короткий формат.

sh.ll > STDOUT # Длинный формат.

Вы, наверное, обратили внимание на то, что в большинстве случаев мы явно отправляем вывод объекту STDOUT. Связано это с тем, что объект Shell автоматически вывод команд никуда не направляет. Он просто ассоциирует его с объектом Filter, который уже может быть связан с файлом или с объектом IO.

14.3.2. Дополнительные замечания по поводу библиотеки shell.rb

Метод transact исполняет блок в контексте вызывающего объекта. Таким образом, допустима следующая сокращенная запись:

sh = Shell.new

sh.transact do

 echo('Строка данных') > 'somefile.txt'

 cat('somefile.txt','otherfile.txt') > 'thirdfile'

 cat('thirdfile') | tee('file4') > STDOUT

end

Итератор foreach принимает в качестве параметра файл или каталог. Если это файл, он перебирает все его строки, а если каталог — все имена файлов в нем.

sh = Shell.new

# Напечатать все строки файла /tmp/foo.

sh.foreach('/tmp/foo') {|l| puts l }

# Вывести список файлов в каталоге /tmp.

sh.foreach('/tmp') {|f| puts f }

Метод pushdir запоминает текущий каталог, а метод popdir делает последний запомненный каталог текущим. У них есть синонимы pushd и popd. Метод pwd возвращает текущий рабочий каталог, его синонимы — getwd, cwd и dir.

sh = Shell.cd '/home'

puts sh.pwd # /home

sh.pushd '/tmp'

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату