Поиск

Вопросы и ответы

Как открыть конвейер, чтобы получить данные от одной программы, обработать их и передать другой программе? Почему не работает оператор наподобие ореn(Р, " | команда |")?

Решение этой простой задачи на деле оказывается гораздо сложнее, чем может показаться на первый взгляд. Причина заключается в том, что попытка чтения и записи в конвейер со стороны одного и того же процесса приводит к взаимной блокировке процессов. В самом деле, после открытия конвейера при попытке выполнить чтение с помощью оператора <Р> ваша программа будет переведена в состояние ожидания появления данных от программы команда. В то же время программа команда будет ожидать появления данных от вашей программы. Таким образом, произойдет взаимная блокировка двух программ, выхода из которой нет. Однако если будет включен режим выдачи предупреждений, интерпретатор Perl выведет сообщение Can't do bidirectional pipe (Нельзя создать двунаправленный конвейер).

Если вы столкнулись с подобной проблемой, воспользуйтесь модулем IPC: :0реn2, с помощью которого можно создать двунаправленный конвейер. Работа с модулями будет описана на 14-м занятии, "Использование модулей".

Почему после выполнения оператора $a=system("команда") переменной $а не присваиваются данные, выведенные командой в стандартный выходной поток, как можно было бы предположить?

Вы перепутали функцию system с обратными кавычками. Эта функция не перехватывает выходные данные программы. Чтобы решить проблему, воспользуйтесь оператором $а= * команда ;.

Почему при запуске внешних команд в системе UNIX с помощью обратных кавычек (' ') не перехватываются сообщения об ошибках?

Дело в том, что всем программам в системе UNIX (в том числе и Perl) назначается два стандартных выходных потока: STDOUT и STDERR. Поток STDOUT используется для вывода обычных сообщений во время работы программы, а поток STDERR — для вывода сообщений об ошибках. При помещении команды в обратные кавычки или открытии конвейера с помощью функции open выполняется перехват только потока STDOUT. Чтобы решить проблему, необходимо с помощью средств командной оболочки перенаправить поток STDERR в STDOUT, как показано ниже:

За более подробной информацией, относящейся к процессу перехвата ошибок, обратитесь к 8-му разделу списка часто задаваемых вопросов по Perl. Для этого введите команду perldoc perlfaq8.