Функция system

Для запуска дочернего процесса в Perl проще всего воспользоваться функцией system. Например, выполнение команды UNIX date в Perl выглядит так:

system "date";

Дочерний процесс выполняет команду date, которая наследует от Perl стандартные потоки ввода, вывода и ошибок. Это означает, что стандартная строка с датой и временем в коротком формате, выдаваемая date, попадает в тот приемник, с которым в Perl уже связан дескриптор STDOUT. В параметре функции system передается строка, которая обычно вводится в командном процессоре для выполнения команды. Таким образом, для более сложных команд (скажем, ls –l $HOME) весь текст придется включить в параметр:

system 'ls -l $HOME';

Обратите внимание: нам пришлось перейти от кавычек к апострофам, так как $HOME является переменной командного процессора. Без апострофов командный процессор не «увидит» знак $, потому что он также является признаком интерполяции переменной для Perl. Конечно, нужный знак можно экранировать в строке:

system "ls -l \$HOME";

Но такая запись быстро становится слишком громоздкой. Команда date только выводит данные. Но предположим, что она также общается с пользователем, спрашивая его: «Для какого часового пояса вы хотите получить время?» Строка попадет в стандартный вывод, а программа будет ожидать поступления данных из стандартного ввода (унаследованного от дескриптора STDIN).


Пользователь видит вопрос, вводит ответ, а date выполняет свою работу. Пока дочерний процесс работает, Perl терпеливо ждет его завершения. Если выполнение команды date занимает 37 секунд, Perl приостановит выполнение программы на эти 37 секунд. Впрочем, вы можете воспользоваться функциональностью командного процессора для запуска процесса в фоновом режиме:

system "long_running_command with parameters &";

Командный процессор получает управление, замечает & в конце командной строки и запускает long_running_command в фоновом режиме. Затем он довольно быстро возвращает управление, Perl замечает это и продолжает выполнение программы. Процесс long_running_command становится «внуком» процесса Perl; последний не имеет ни прямого доступа к нему, ни информации о его существовании. Если команда «достаточно проста», командный процессор вообще не задействуется. Так, упоминавшиеся ранее команды date и ls Perl запускает напрямую, для чего он ищет команду по унаследованному значению PATH. Но если в строке есть чтоQто необычное (например, метасимволы командного процессора: $, ; или |), для ее обработки активизируется стандартный командный процессор Bourne Shell (/bin/sh2).


В этом случае дочерним процессом является командный процессор, а запрашиваемая команда становится «внуком» (или потомком следующего уровня). Например, вы можете записать в аргументе целый мини-сценарий командного процессора:

system 'for i in *; do echo == $i ==; cat $i; done';

Мы снова используем апострофы, потому что знак $ предназначается для командного процессора, а не для Perl. С кавычками Perl заменит $i текущим значением переменной и не позволит командному процессору использовать свое значение.3 Кстати говоря, этот мини-сценарий перебирает все обычные файлы текущего каталога, выводя их имена и значения; если не верите, убедитесь сами.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Perl на эту тему:
Ветвление
Выполнение команд в обход командного процессора
Обратные апострофы в списочном контексте
Обратные апострофы и сохранение вывода
Отправка и прием сигналов

Вернуться в раздел: Perl / 15. Управление процессами