Краткий ответ: Command >filename 2>&1
или Command &>filename
Пояснение:
Рассмотрим следующий код, который печатает слово «stdout» в stdout и слово «stderror» в stderror.
$ (echo "stdout"; echo "stderror" >&2)
stdout
stderror
Обратите внимание, что оператор '&' сообщает bash, что 2 - это дескриптор файла (который указывает на stderr), а не имя файла. Если мы пропустим '&', эта команда выведет stdout
в стандартный вывод, создаст файл с именем "2" и напишет stderror
.
Экспериментируя с приведенным выше кодом, вы можете сами убедиться, как именно работают операторы перенаправления. Например, изменяя, какой файл, какой из двух дескрипторов 1,2
, перенаправляется на /dev/null
, следующие две строки кода удаляют все из stdout и все из stderror соответственно (печатая то, что остается).
$ (echo "stdout"; echo "stderror" >&2) 1>/dev/null
stderror
$ (echo "stdout"; echo "stderror" >&2) 2>/dev/null
stdout
Теперь мы можем объяснить, почему решение, почему следующий код не производит вывод:
(echo "stdout"; echo "stderror" >&2) >/dev/null 2>&1
Чтобы по-настоящему понять это, я настоятельно рекомендую вам прочитать эту веб-страницу в таблицах файловых дескрипторов . Предполагая, что вы сделали это чтение, мы можем продолжить. Обратите внимание, что Bash обрабатывает слева направо; таким образом, Bash сначала видит >/dev/null
(что совпадает с 1>/dev/null
) и устанавливает дескриптор файла 1 так, чтобы он указывал на / dev / null вместо stdout. Сделав это, Bash двигается вправо и видит 2>&1
. Это устанавливает дескриптор файла 2 так, чтобы он указывал на тот же файл , что и дескриптор файла 1 (а не на сам дескриптор файла 1 !!!! (для получения дополнительной информации см. этот ресурс по указателям ) ) Поскольку файловый дескриптор 1 указывает на / dev / null, а файловый дескриптор 2 указывает на тот же файл, что и файловый дескриптор 1, файловый дескриптор 2 теперь также указывает на / dev / null. Таким образом, оба файловых дескриптора указывают на / dev / null, и поэтому вывод не производится.
Чтобы проверить, действительно ли вы понимаете концепцию, попробуйте угадать вывод при переключении порядка перенаправления:
(echo "stdout"; echo "stderror" >&2) 2>&1 >/dev/null
Причиной здесь является то, что при оценке слева направо Bash видит 2> & 1 и, таким образом, устанавливает дескриптор файла 2 так, чтобы он указывал на то же место, что и дескриптор файла 1, то есть stdout. Затем он устанавливает файловый дескриптор 1 (помните, что> / dev / null = 1> / dev / null), чтобы он указывал на> / dev / null, удаляя, таким образом, все, что обычно отправляется стандарту. Таким образом, все, что нам осталось, это то, что не было отправлено на стандартный вывод в подоболочке (код в скобках) - то есть "stderror".
Интересно отметить, что хотя 1 является просто указателем на стандартный вывод, перенаправление указателя с 2 на 1 через 2>&1
НЕ формирует цепочку указателей 2 -> 1 -> стандартный вывод. Если это произойдет, то в результате перенаправления 1 в / dev / null код 2>&1 >/dev/null
даст цепочку указателей 2 -> 1 -> / dev / null, и, следовательно, код ничего не сгенерирует, в отличие от того, что мы видел выше.
Наконец, я бы отметил, что есть более простой способ сделать это:
Из раздела 3.6.4 здесь мы видим, что мы можем использовать оператор &>
для перенаправления как stdout, так и stderr. Таким образом, чтобы перенаправить вывод stderr и stdout любой команды на \dev\null
(который удаляет вывод), мы просто набираем
$ command &> /dev/null
или в случае моего примера:
$ (echo "stdout"; echo "stderror" >&2) &>/dev/null
Ключевые выносы:
- Файловые дескрипторы ведут себя как указатели (хотя файловые дескрипторы не совпадают с файловыми указателями)
- Переадресация файлового дескриптора "a" на файловый дескриптор "b", который указывает на файл "f", заставляет файловый дескриптор "a" указывать на то же место, что и файловый дескриптор b - файл "f". НЕ образует цепочку указателей a -> b -> f
- Из-за вышеизложенного порядок имеет значение,
2>&1 >/dev/null
равно! = >/dev/null 2>&1
. Один генерирует вывод, а другой нет!
Наконец, взгляните на эти замечательные ресурсы:
Документация Bash по перенаправлению , Объяснение таблиц файловых дескрипторов , Введение в указатели