Чтение из стандартного потока ошибок программы

Задача
Необходимо читать программный вывод ошибок. Например, требуется перехватить системные вызовы, показываемые strace(1).

Решение
Перенаправьте стандартный поток ошибок в стандартный поток вывода, добавив 2>&1 в командную строку, передаваемую функции popen().

Прочитайте стандартный поток вывода, открыв канал в режиме r:

$ph = popen('strace ls 2>&1','r') or die($php_errormsg);
while (!feof($ph)) {
$s = fgets($ph,1048576) or die($php_errormsg);
}
pclose($ph) or die($php_errormsg);

Обсуждение
И в оболочке UNIX sh, и в оболочке Windows cmd.exe стандартный поток ошибок представляет файловый дескриптор 2, а стандартный поток вывода – файловый дескриптор 1. Добавление 2>&1 в команднуюстроку приказывает оболочке перенаправить то, что обычно направляется в файловый дескриптор 2 (стандартный поток ошибок), в файловый дескриптор 1 (стандартный поток вывода). Затем функция fgets() читает и стандартный поток ошибок, и стандартный поток вывода.

Этот способ позволяет читать стандартный поток ошибок, но не дает возможности отличить его от стандартного потока вывода. Для того чтобы читать исключительно стандартный поток ошибок, нельзя допустить возвращение стандартного потока вывода через канал. Это делается путем перенаправления его в /dev/null в UNIX и в NUL в Windows:

// UNIX: читаем только стандартный поток ошибок
$ph = popen('strace ls 2>&1 1>/dev/null','r') or die($php_errormsg);
// Windows: читаем только стандартный поток ошибок
$ph = popen('ipxroute.exe 2>&1 1>NUL','r') or die($php_errormsg);

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

Статьи из раздела PHP на эту тему:
Блокировка файла
Выбор случайной строки из файла
Запись в несколько файловых дескрипторов одновременно
Запись в стандартный поток вывода
Непосредственная модификация файла без временной копии

Вернуться в раздел: PHP / 18. Файлы