sleep 2

Process.kill(1,0) # Послать самому себе.

О применениях метода trap в более сложных ситуациях читайте в документации по Ruby и UNIX.

В модуле Process есть также методы для опроса и установки таких атрибутов процесса, как идентификатор пользователя, действующий идентификатор пользователя, приоритет и т.д. Дополнительную информацию вы отыщете в справочном руководстве по Ruby.

14.1.4. Стандартный ввод и вывод

В главе 10 мы видели, как работают методы IO.popen и IO.pipe, но существует еще небольшая библиотека, которая иногда бывает удобна.

В библиотеке Open3.rb есть метод popen3, который возвращает массив из трех объектов IO. Они соответствуют стандартному вводу, стандартному выводу и стандартному выводу для ошибок того процесса, который был запущен методом popen3. Вот пример:

require 'open3'

filenames = %w[ file1 file2 this that another one_more ]

inp, out, err = Open3.popen3('xargs', 'ls', '-l')

filenames.each { |f| inp.puts f } # Писать в stdin процесса.

inp.close                         # Закрывать обязательно!

output = out.readlines            # Читать из stdout.

errout = err.readlines            # Читать также из stderr.

puts 'Послано #{filenames.size} строк входных данных.'

puts 'Получено #{output.size} строк из stdout'

puts 'и #{errout.size} строк из stderr.'

В этом искусственном примере мы выполняем команду ls -l для каждого из заданных имен файлов и по отдельности перехватываем стандартный вывод и стандартный вывод для ошибок. Отметим, что вызов close необходим, чтобы порожденный процесс увидел конец файла. Также отметим, что в библиотеке Open3 используется метод fork, не реализованный на платформе Windows; для этой платформы придется пользоваться библиотекой win32-open3 (ее написали и поддерживают Дэниэль Бергер (Daniel Berger) и Парк Хисоб (Park Heesob)). См. также раздел 14.3.

14.2. Флаги и аргументы в командной строке

Слухи о кончине командной строки сильно преувеличены. Хоть мы и живем в век графических интерфейсов, ежедневно тысячи и тысячи программистов по тем или иным причинам обращаются к командным утилитам.

Мы уже говорили, что корнями своими Ruby уходит в UNIX. Но даже в Windows существует понятие командной строки, и, честно говоря, мы не думаем, что в обозримом будущем она исчезнет.

На этом уровне для управления работой программы применяются аргументы и флаги. О них мы и поговорим ниже.

14.2.1. Разбор флагов в командной строке

Для разбора командной строки чаще всего применяется библиотека getoptlong (библиотека getopts.rb, обладающая менее развитой функциональностью, считается устаревшей). Она понимает однобуквенные и длинные флаги и распознает двойной дефис (-- ) как признак конца флагов. В целом библиотека ведет себя так же, как соответствующие функции GNU.

Необходимо создать объект класса GetoptLong, который и будет выполнять функции анализатора. Затем ему передаются допустимые значения флагов, а он извлекает их по одному.

У объекта-анализатора есть метод set_options, который принимает список массивов. Каждый массив содержит один или несколько флагов (в виде строк) и один «признак наличия аргумента», который говорит, должны ли эти флаги сопровождаться аргументами. Все флаги в одном массиве считаются синонимами; первый из них является «каноническим именем», которое и возвращает операция get.

Предположим, что имеется программа, понимающая следующие флаги: -h или --help (печать справки), -f или --file (указание имени файла), -l или --lines (вывод не более указанного числа строк, по умолчанию 100).

Такая программа могла бы начинаться следующим образом:

require 'getoptlong'

parser = GetoptLong.new

parser.set_options(

 ['-h', '--help', GetoptLong::NO_ARGUMENT],

 ['-f', '--file', GetoptLong::REQUIRED_ARGUMENT],

 ['-l', '--lines', GetoptLong::OPTIONAL_ARGUMENT])

Теперь можно в цикле вызвать метод get (см. листинг 14.1). Наличие операторных скобок begin-end имитирует цикл с проверкой условия в конце. У метода get есть синоним get_option, существуют также итераторы each и each_option, которые в точности идентичны.

Листинг 14.1. Получение флагов из командной строки

filename = nil

lines = 0          # По умолчанию вывод не усекается.

loop do

 begin

  opt, arg = parser.get

  break if not opt

  # Только для отладки...

  puts (opt +' => ' + arg)

  case opt

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

0

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

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