Почему эта команда grep не работает?

24

Когда я пытаюсь использовать grep таким образом:

service --status-all | grep network

В нем по-прежнему перечислены все службы, хотя я подключил его, grepчтобы ограничить его только строкой «сети»


После факта:

Обратите внимание на эту статью, которая объясняет, почему команда ведет себя так, это то, что мне нравится в Linux, всегда есть веская причина, но не обязательно, интуитивно понятный

Меер Борг
источник

Ответы:

41

Пытаться:

service --status-all |& grep network

Приложения командной строки могут печатать в два текстовых потока, известные как стандартное завершение (stdout) и стандартная ошибка (stderr). По умолчанию терминал просто отображает вывод для обоих идентично.

Stdout дается номер 1, и STDERR дается номер 2. По умолчанию, операторы перенаправления, как >, |и <распространяются только на стандартный вывод, номер 1.

|&направляет и stdout, и stderr вместе к процессу в стандартном входном потоке справа (stdin), что делает grepработу, как вы ожидали.

Я не знаю, зачем service --status-allздесь печатать в stderr, но в целом очень полезно иметь отдельный поток stderr, так как он позволяет вам видеть ошибки, даже когда stdout отключен.

Флимм
источник
Спасибо за ответ, кажется, это вызвало большой интерес. Так что, думаю, я был не единственным с этой проблемой.
Меер Борг
4

Вам нужно перенаправить стандартный поток ошибок ( 2) в стандартный вывод ( 1):

service --status-all 2>&1 | grep network

Оператор >обычно перенаправляет в файл (например 2>/tmp/file). Для перенаправления в другой поток с использованием дескриптора ему должен предшествовать &(обратите внимание, пробелы между символами отсутствуют).

Павел Надольский
источник