Почему 2>&1, а не 2>>&1 для добавления в файл журнала
Я перенаправляю STDOUT и STDERR в один файл, постоянно растущий, поэтому я всегда использую перенаправление "добавить"; это >>
моя команда command >> logfile 2>&1
И это работает.
Но перенаправление STDERR имеет один >
, который я использовал, чтобы "создать" файл, удалив предыдущий, как в command > outlog 2> errlog
Почему он не стирает файл журнала в этом случае?
2 ответа
Когда вы перенаправляете что-то &number
вы вообще не открываете новый файл; Вы повторно используете уже открытый файл вместе с тем режимом, в котором он был открыт.
Цифры относятся к дескрипторам "открыть файл" (дескрипторы файлов). Так что нет никакой технической разницы между тем, как >&
а также >>&
(и действительно <&
) будет работать - все они означают "клонировать существующий дескриптор файла с помощью dup()".
То есть, 2>&1
указывает, что файловый дескриптор #1 (который вы ранее открывали для добавления с помощью >>logfile
) клонируется в номер 2. И да, 2<&1
работает одинаково.
Дополнительное техническое примечание: добавление к усечению не является явным действием, выполняемым оболочкой; на самом деле это режим, который оболочка указывает при открытии файла, а остальное выполняет сама ОС. Например, когда вы используете >
оболочка не стирает старое содержимое вручную, она просто добавляет O_TRUNC при вызове open(). Поэтому, когда open () вообще не вызывается, предыдущий режим остается неизменным.
Последовательность command >> logfile 2>&1
имеет две стадии перенаправления:
command >> logfile
добавит в лог файл2>&1
перенаправит stderr в stdout (который сам добавляется в файл журнала)
Так command >> logfile 2>&1
не будет обрезать файл журнала, пока command >>logfile 2>logfile
было бы.