Программирование на языке Ruby - [171]

Шрифт
Интервал

). Ниже приведены примеры запуска внешней и встроенной команды:

>system("notepad.ехе","myfile.txt") # Никаких проблем...

>system("cmd /с dir","somefile")    # 'dir' - встроенная команда!

Другое решение — воспользоваться библиотекой >Win32API и определить собственный вариант метода >system.

>require "Win32API"


>def system(cmd)

> sys = Win32API.new("crtdll", "system", ['P'], 'L')

> sys.Call(cmd)

>end


>system("dir") # cmd /с необязательно!

Таким образом, можно добиться более-менее системно-независимого поведения >system. Но если вы хотите запомнить выведенную программой информацию (например, в переменной), то >system — не лучший способ (см. следующий раздел).

Упомяну еще метод >exec. Он ведет себя аналогично >system с тем отличием, что новый процесс замещает текущий. Поэтому код, следующий за >exec, исполняться не будет.

>puts "Содержимое каталога:"

>exec("ls", "-l")


>puts "Эта строка никогда не исполняется!"

14.1.2. Перехват вывода программы

Простейший способ перехватить информацию, выведенную программой, — заключить команду в обратные кавычки, например:

>listing = `ls -l` # Одна строка будет содержать несколько строчек (lines).

>now = `date`      # "Mon Mar 12 16:50:11 CST 2001"

Обобщенный ограничитель >%x вызывает оператор обратных кавычек (который в действительности является методом модуля Kernel). Работает он точно так же:

>listing = %x(ls -l)

>now = %x(date)

Применение >%x бывает полезно, когда подлежащая исполнению строка содержит такие символы, как одиночные и двойные кавычки.

Поскольку обратные кавычки — это на самом деле метод (в некотором смысле), то его можно переопределить. Изменим его так, чтобы он возвращал не одну строку, а массив строк. Конечно, при этом мы создадим синоним старого метода, чтобы его можно было вызвать.

>alias old_execute `


>def `(cmd)

> out = old_execute(cmd) # Вызвать исходный метод обратной кавычки.

> out.split("\n") # Вернуть массив строк!

>end


>entries = `ls -l /tmp`

>num = entries.size          # 95


>first3lines = %x(ls -l | head -n 3)

>how_many = first3lines.size # 3

Как видите, при таком определении изменяется также поведение ограничителя >%x.

В следующем примере мы добавили в конец команды конструкцию интерпретатора команд, которая перенаправляет стандартный вывод для ошибок в стандартный вывод:

>alias old_execute `


>def `(cmd)

> old_execute(cmd + " 2>&1")

>end


>entries = `ls -l /tmp/foobar`

># "/tmp/foobar: No such file or directory\n"

Есть, конечно, и много других способов изменить стандартное поведение обратных кавычек.

14.1.3. Манипулирование процессами

В этом разделе мы обсудим манипулирование процессами, хотя создание нового процесса необязательно связано с запуском внешней программы. Основной способ создания нового процесса — это метод >fork, название которого в соответствии с традицией UNIX подразумевает разветвление пути исполнения, напоминая развилку на дороге. (Отметим, что в базовом дистрибутиве Ruby метод >fork на платформе Windows не поддерживается.)

Метод >fork, находящийся в модуле >Kernel (а также в модуле >Process), не следует путать с одноименным методом экземпляра в классе >Thread.

Существуют два способа вызвать метод >fork. Первый похож на то, как это обычно делается в UNIX, — вызвать и проверить возвращенное значение. Если оно равно >nil, мы находимся в дочернем процессе, в противном случае — в родительском. Родительскому процессу возвращается идентификатор дочернего процесса (pid).

>pid = fork

>if (pid == nil)

> puts "Ага, я, должно быть, потомок."

> puts "Так и буду себя вести."

>else

> puts "Я родитель."

> puts "Пора отказаться от детских штучек."

>end

В этом не слишком реалистичном примере выводимые строки могут чередоваться, а может случиться и так, что строки, выведенные родителем, появятся раньше. Но сейчас это несущественно.

Следует также отметить, что процесс-потомок может пережить своего родителя. Для потоков в Ruby это не так, но системные процессы — совсем другое дело.

Во втором варианте вызова метод >fork принимает блок. Заключенный в блок код выполняется в контексте дочернего процесса. Так, предыдущий вариант можно было бы переписать следующим образом:

>fork do

> puts "Ага, я, должно быть, потомок."

> puts "Так и буду себя вести."

>end


>puts "Я родитель."

>puts "Пора отказаться от детских штучек."

Конечно, pid по-прежнему возвращается, мы просто не показали его.

Чтобы дождаться завершения процесса, мы можем вызвать метод >wait из модуля >Process. Он ждет завершения любого потомка и возвращает его идентификатор. Метод >wait2 ведет себя аналогично, только возвращает массив, содержащий РМ, и сдвинутый влево код завершения.

>Pid1 = fork { sleep 5; exit 3 }

>Pid2 = fork { sleep 2; exit 3 }


>Process.wait  # Возвращает pid2

>Process.wait2 # Возвращает [pid1,768]

Чтобы дождаться завершения конкретного потомка, применяются методы >waitpid и >waitpid2.

>pid3 = fork { sleep 5; exit 3 }

>pid4 = fork { sleep 2; exit 3 }


>Process.waitpid(pid4,Process::WNOHANG)   # Возвращает pid4

>Process.waitpid2(pid3, Process::WNOHANG) # Возвращает [pid3,768]

Если второй параметр не задан, то вызов может блокировать программу (если такого потомка не существует). Второй параметр можно с помощью ИЛИ объединить с флагом


Рекомендуем почитать
Графика DirectX в Delphi

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Вторая жизнь старых компьютеров

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


DirectX 8. Начинаем работу с DirectX Graphics

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.