Страницы

Поиск по вопросам

вторник, 13 ноября 2018 г.

Как перенаправить вывод функции в pipe?

Здесь pipe работает нормально:
dpkg -l | grep nginx
ii nginx 1.4.6-1ubuntu3.2 all small, powerful, scalable web/proxy server ii nginx-common 1.4.6-1ubuntu3.2 all small, powerful, scalable web/proxy server - common files ii nginx-full 1.4.6-1ubuntu3.2 amd64 nginx web/proxy server (standard version)
А вот так вывод первого выражения пролетает мимо grep:
nginx -V | grep echo
nginx version: nginx/1.4.6 (Ubuntu) built by gcc 4.8.2 (Ubuntu 4.8.2-19ubuntu1) TLS SNI support enabled configure arguments: ...
(дальше идет список аргументов, в котором тоже нет слова "echo").
Как можно увидеть, 4 строки печатаются прямо в stdout и не попадают в pipe. А можно ли их всё-таки поймать и обработать? Как?


Ответ

процесс может читать информацию как минимум из одного потока, условно называемого stdin (поток номер 0), и выводить информацию как минимум в два потока, условно называемые stdout (поток номер 1) и stderr (поток номер 2).
оператор shell-а | ("pipe", "вертикальная черта"), употреблённый между двумя командами (которые запускают процессы), связывает stdout первого процесса с stdin второго процесса. и второй процесс может этот поток информации как-то обработать.
но та информация, которую первый процесс отправляет в stderr, «проходит мимо» оператора |, а значит, и «мимо» второго процесса.

с помощью оператора 2>&1, вставленного до или после команды, можно «изменить направление» потока stderr (поток номер 2) процесса, созданного этой командой, так, что выводимая процессом в этот поток информация будет «попадать» в поток stdout (поток номер 1). поток stderr «как бы исчезнет», а в потоке stdout будет (вперемешку) присутствовать вся информация, выданная в оба этих потока. таким образом оператору | (а значит, и второму процессу) попадёт и содержимое stdout, и содержимое stderr первого процесса.

т.е., возвращаясь к вопросу, можно переписать команду так:
$ /usr/sbin/nginx -V 2>&1 | grep echo
или так:
$ 2>&1 /usr/sbin/nginx -V | grep echo

у реализации shell-а под названием bash (возможно, и у других реализаций) есть не описанная в стандарте posix сокращённая форма записи этих двух операторов. вместо 2>&1 | можно писать |&
$ /usr/sbin/nginx -V |& grep echo

Комментариев нет:

Отправить комментарий