Здесь 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
Комментариев нет:
Отправить комментарий