причина последняя команда Вы заключили в кавычки:
cmd 1>/dev/null 2>&1 | grep pattern
не работает, основы от беспорядка на порядке, в котором работает перенаправление. Вы ожидали, что последнее заключенное в кавычки перенаправление будет применено к тем перед ним на каждом выводе, так, чтобы произведенный исходный дескриптор файла стандартного вывода (1) перешел к/dev/null, и производить к дескриптору файла стандартной погрешности (2), перейдет к исходному стандартному выводу.
Однако это не то, как перенаправление оболочки работает. Каждое перенаправление заставляет дескрипторы файлов быть "повторно отображенными" путем закрытия "источника" и дублирования "места назначения" в него (см. man
страницы dup(2)
и close(2)
), в порядке. Это означает, что в Вашем стандартном выводе команды сначала заменяется /dev/null
, и затем стандартная погрешность, замененная стандартным выводом, который уже является /dev/null
.
Поэтому для получения желаемого эффекта просто необходимо инвертировать перенаправления. Затем у Вас будет стандартная погрешность, переходят к стандартному выводу, и исходный стандартный вывод переходит в /dev/null
:
cmd 2>&1 >/dev/null | grep pattern
(отмечают, что 1
прежде >
является ненужным - для стандартного вывода перенаправления вывода, значение по умолчанию)
Приложение : Charlie упомянул, что перенаправил к [1 111] для закрытия дескриптора файла. При использовании интерактивной оболочки, которая поддерживает то расширение (bash
и некоторые другие реализации делают, но не все и это не стандартно ), можно также сделать это как это:
cmd 2>&1 >&- | grep pattern
Это может быть лучше - это может сэкономить некоторое время, потому что, когда команда пытается записать в стандартный вывод, вызов к [1 113] может сразу перестать работать, не ожидая контекстного переключения в ядро и драйвера, обрабатывающего /dev/null
(в зависимости от реализации системного вызова - некоторые могут поймать это в эти libc
функция, и у некоторых может также быть специальная обработка для [1 116]). Если существует большой вывод, который может стоить, и это быстрее для ввода.
Это будет главным образом работать, потому что большинство программ не заботится, не удается ли им записать в стандартный вывод (кто действительно проверяет возвращаемое значение [1 117]?) и не будет возражать, тот стандартный вывод закрывается. Но некоторые программы могут прыгнуть с парашютом с кодом неисправности если write
сбои - обычно процессоры блока, программы, пользующиеся некоторой осторожной библиотекой для ввода-вывода или регистрирующиеся к выводу stdandard. Таким образом, если это не работает, помнят, что это - вероятная причина, и попробуйте /dev/null
.
Я попробовал бы что-то простое как:
cmd 2> tmp_file && cat tmp_file | grep pattern && rm -f tmp_file