Давайте посмотрим, что произойдет, когда команда выдает ошибку. Попробуйте вывести содержимое несуществующего каталога и перенаправить вывод в файл с именем peanuts.txt.
ls /fake/directory > peanuts.txt
Вместо чистого приглашения вы увидите сообщение об ошибке на экране:
ls: cannot access /fake/directory: No such file or directory
Возможно, вы задаетесь вопросом, почему это сообщение не было отправлено в файл. Это потому, что в игру вступает другой поток ввода-вывода: стандартный вывод ошибок, или stderr.
Что такое стандартный вывод ошибок (Standard Error) в Linux?
В Linux stderr — это поток вывода по умолчанию, используемый программами для отправки сообщений об ошибках и диагностики. Он полностью отделен от потока стандартного вывода (stdout), который используется для обычного вывода программы. По умолчанию и stdout, и stderr отправляют свой вывод на экран вашего терминала, поэтому вы видите сообщение об ошибке напрямую.
Чтобы управлять stderr, вам потребуется другой метод перенаправления.
Понимание файловых дескрипторов
Для управления потоками ввода-вывода, такими как stdin, stdout и stderr, система использует файловые дескрипторы. Файловый дескриптор — это неотрицательное число, которое ядро использует для идентификации открытого файла или потока. Стандартные файловые дескрипторы:
0: stdin (стандартный ввод)1: stdout (стандартный вывод)2: stderr (стандартный вывод ошибок)
Число 2 — это выделенный файловый дескриптор stderr, и мы можем использовать его для управления тем, куда отправляются сообщения об ошибках.
Перенаправление stderr в файл
Чтобы перенаправить stderr в файл, вы используете файловый дескриптор 2, за которым следует оператор >. Эта команда отправит любые сообщения об ошибках в указанный файл stderr.
ls /fake/directory 2> peanuts.txt
Теперь ваш терминал будет молчать, а сообщение об ошибке будет находиться внутри peanuts.txt.
Объединение stdout и stderr
Что, если вы хотите зафиксировать как обычный вывод, так и сообщения об ошибках в одном и том же файле? Вы можете добиться этого, перенаправив оба потока.
ls /fake/directory /etc/passwd > peanuts.txt 2>&1
Давайте разберем это:
> peanuts.txtперенаправляетstdout(файловый дескриптор 1) в файлpeanuts.txt.2>&1перенаправляетstderr(файловый дескриптор 2) в то же место, на которое в данный момент указываетstdout(файловый дескриптор 1).
Порядок важен. 2>&1 отправляет stderr в текущее место назначения stdout. В данном случае stdout указывает на файл, поэтому stderr также отправляется в этот файл.
Более современный и короткий способ перенаправить как stdout, так и stderr — использовать &>.
ls /fake/directory /etc/passwd &> peanuts.txt
Отбрасывание сообщений об ошибках
Иногда вы можете захотеть запустить команду и полностью проигнорировать любые потенциальные сообщения об ошибках. Для этого вы можете перенаправить stderr в специальный файл под названием /dev/null, который отбрасывает любые данные, записанные в него.
ls /fake/directory 2> /dev/null
Эта команда выполнится, и любой вывод ошибок из stderr будет отправлен в /dev/null и отброшен, оставляя ваш экран чистым.