В оболочке Unix, если я хочу объединить stderr
и stdout
в stdout
поток для дальнейших манипуляций, я могу добавить следующее в конце моей команды:
2>&1
Итак, если я хочу использовать head
на выходе из g++
, я могу сделать что-то вроде этого:
g++ lots_of_errors 2>&1 | head
поэтому я вижу только первые несколько ошибок.
У меня всегда возникают проблемы с запоминанием этого, и мне постоянно приходится искать его, и это главным образом потому, что я не полностью понимаю синтаксис этого конкретного трюка.
Может кто-то разбить это и объяснить символ за символом, что 2>&1
значит?
2>&1
чем 2> / dev / null ;-)|&
это сокращение от,2>&1 |
если вы используете zsh. Я не могу сказать, относится ли это к другим подобным борну оболочкам или это только функция zsh.Ответы:
Файловый дескриптор 1 - это стандартный вывод (
stdout
).Файловый дескриптор 2 является стандартной ошибкой (
stderr
).Вот один способ запомнить эту конструкцию (хотя это и не совсем точно): во - первых,
2>1
может выглядеть как хороший способ , чтобы переадресоватьstderr
кstdout
. Однако на самом деле это будет интерпретироваться как «перенаправлениеstderr
в файл с именем1
».&
указывает, что то, что следует, является дескриптором файла, а не именем файла. Таким образом, конструкция становится:2>&1
.источник
&2>&1
?&
интерпретируется как «дескриптор файла» только в контексте перенаправлений. Записьcommand &2>&
анализируется какcommand &
и2>&1
, т. Е. «Выполняетсяcommand
в фоновом режиме, затем запускает команду2
и перенаправляет ее стандартный вывод в стандартный вывод».2>'&1'
перенаправляет стандартный вывод на
afile.txt
. Это то же самое, что делатьЧтобы перенаправить stderr, вы должны:
>&
это синтаксис для перенаправления потока в другой файловый дескриптор - 0 - это стандартный ввод, 1 - стандартный вывод, а 2 - стандартный вывод.Вы можете перенаправить stdout в stderr, выполнив:
Или наоборот:
Итак, короче ...
2>
перенаправляет stderr в (неопределенный) файл, добавляя&1
перенаправляет stderr в stdout.источник
java ... 2&1 >> data.log
я видел, что один из моих коллег сделал это?cmd 2>&1 >> somefile.log
добавит stdout / stderr в файл - это в основном то же, что и выше, с>> file
добавлениемcmd 2>&1 >>file
не перенаправляет stderr в файл, ноcmd >> file 2>&1
делает. Заказ имеет значение. В первом случае stderr перенаправляется на стандартный вывод оболочки (возможно, tty, если команда вводится в интерактивном режиме), а затем стандартный вывод направляется в файл. Во втором случае stdout направляется в файл, а затем stderr направляется в то же место.0(or 1,2)>&0(or 1,2)
как опция для управления выходом? Это такecho test >test.log 2>&1
же, какecho test 2>&1 >test.log
?Некоторые хитрости о перенаправлении
Некоторые особенности синтаксиса могут иметь важные особенности. Существует несколько маленьких образцов около перенаправлений
STDERR
,STDOUT
и аргументы упорядоченности .1 - перезаписать или добавить?
Символ
>
означает перенаправление .>
означает отправку в виде всего завершенного файла с перезаписью цели, если она существует (см.noclobber
функцию bash на # 3 позже).>>
означает отправить в дополнение к добавлению к цели, если существует.В любом случае файл будет создан, если они не существуют.
2 - командная строка оболочки зависит от порядка !!
Для проверки нам нужна простая команда, которая отправит что-то на оба вывода :
(Ожидая, что у вас нет каталога с именем
/tnt
, конечно;). Ну, у нас это есть !!Итак, давайте посмотрим:
Последняя командная строка выводит данные
STDERR
на консоль, и это, кажется, не ожидаемое поведение ... Но ...Если вы хотите сделать некоторую пост-фильтрацию для одного выхода, другого или обоих:
Обратите внимание, что последняя командная строка в этом абзаце точно такая же, как и в предыдущем абзаце, где я написал , что это не ожидаемое поведение (так что это может быть даже ожидаемое поведение).
Ну, есть несколько хитростей по поводу перенаправлений для выполнения разных операций на обоих выходах :
Примечание:
&9
дескриптор возникнет самопроизвольно из-за) 9>&2
.Приложение: нота! С новой версиейудар(
>4.0
) есть новая функция и более привлекательный синтаксис для таких вещей:И, наконец, для такого каскадного форматирования вывода:
Приложение: нота! Тот же новый синтаксис, в обоих направлениях:
Где
STDOUT
проходит определенный фильтр,STDERR
другой и, наконец, оба слитых выхода проходят через третий фильтр команд.3 - Слово о
noclobber
опции и>|
синтаксисеЭто о перезаписи :
В то время как
set -o noclobber
команда bash не перезаписывает ни один из существующих файлов,>|
синтаксис позволяет вам преодолеть это ограничение:Файл перезаписывается каждый раз, а теперь:
Пройдите через
>|
:Отключение этой опции и / или запрос, если он уже установлен.
4 - Последний трюк и многое другое ...
Для перенаправления обоих выходных данных из данной команды мы видим, что правильный синтаксис может быть:
для этого особого случая есть сокращенный синтаксис:
&>
... или>&
Примечание: если
2>&1
существует,1>&2
правильный синтаксис тоже:4b- Теперь я дам вам подумать о:
4c- Если вы заинтересованы в дополнительной информации
Вы можете прочитать прекрасное руководство, нажав:
в удар приставка ;-)
источник
Я нашел этот блестящий пост о перенаправлении: Все о перенаправлениях
Перенаправить как стандартный вывод, так и стандартную ошибку в файл
Этот однострочник использует
&>
оператор для перенаправления обоих потоков вывода - stdout и stderr - из команды в файл. Это ярлык Bash для быстрого перенаправления обоих потоков в одно и то же место.Вот как выглядит таблица файловых дескрипторов после того, как Bash перенаправил оба потока:
Как вы можете видеть, и stdout, и stderr теперь указывают на
file
. Таким образом, все, что пишется в stdout и stderr, записывается вfile
.Есть несколько способов перенаправить оба потока в один и тот же пункт назначения. Вы можете перенаправить каждый поток один за другим:
Это гораздо более распространенный способ перенаправления обоих потоков в файл. Сначала stdout перенаправляется в файл, а затем stderr дублируется, чтобы быть таким же, как stdout. Таким образом, оба потока в конечном итоге указывают на
file
.Когда Bash видит несколько перенаправлений, он обрабатывает их слева направо. Давайте пройдемся по шагам и посмотрим, как это происходит. Перед выполнением каких-либо команд таблица дескрипторов файлов Bash выглядит следующим образом:
Теперь Bash обрабатывает первый файл перенаправления>. Мы видели это раньше, и это превращает стандартный вывод в файл:
Далее Bash видит второе перенаправление 2> & 1. Мы не видели этого перенаправления раньше. Этот дубликат файлового дескриптора 2 является копией файлового дескриптора 1, и мы получаем:
Оба потока были перенаправлены в файл.
Однако будьте осторожны здесь! Письмо
это не то же самое, что писать:
Порядок переадресации имеет значение в Bash! Эта команда перенаправляет только стандартный вывод в файл. Stderr все еще будет печатать в терминал. Чтобы понять, почему это происходит, давайте снова пройдемся по шагам. Поэтому перед запуском команды таблица дескриптора файла выглядит следующим образом:
Теперь Bash обрабатывает перенаправления слева направо. Сначала он видит 2> & 1, поэтому дублирует stderr в stdout. Таблица дескрипторов файлов становится:
Теперь Bash видит второе перенаправление
>file
и перенаправляет стандартный вывод в файл:Вы видите, что здесь происходит? Stdout теперь указывает на файл, но stderr по-прежнему указывает на терминал! Все, что записывается в stderr, все равно выводится на экран! Так что будьте очень, очень осторожны с порядком перенаправлений!
Также обратите внимание, что в Bash пишется
точно так же, как:
источник
>&
/dev/tty0
?Числа относятся к файловым дескрипторам (fd).
stdin
stdout
stderr
2>&1
перенаправляет FD 2 на 1.Это работает для любого числа файловых дескрипторов, если программа использует их.
Вы можете посмотреть,
/usr/include/unistd.h
если вы забудете их:Тем не менее, я написал инструменты C, которые используют нестандартные файловые дескрипторы для пользовательского ведения журнала, поэтому вы не увидите его, если не перенаправите его в файл или что-то еще.
источник
Эта конструкция отправляет стандартную ошибку stream (
stderr
) в текущее местоположение стандартного вывода (stdout
) - эта проблема с валютой, похоже, игнорируется другими ответами.Используя этот метод, вы можете перенаправить любой выходной дескриптор на другой, но чаще всего он используется для направления
stdout
иstderr
потоков в один поток для обработки.Вот некоторые примеры:
Обратите внимание , что этот последний будет не направлять
stderr
наoutfile2
- он перенаправляет его на то , чтоstdout
было , когда аргумент встречались (outfile1
) и затем перенаправляетstdout
кoutfile2
.Это допускает некоторые довольно сложные хитрости.
источник
some_program 2>&1 > /dev/null
не работает так:some_program > /dev/null 2>&1
.2>&1
является оболочкой POSIX Вот разбивка, токен по токену:2
: Дескриптор выходного файла « Стандартная ошибка ».>&
: Дублировать оператор дескриптора выходного файла (вариант оператора перенаправления вывода>
). Учитывая[x]>&[y]
, дескриптор файла, обозначенныйx
как, сделан, чтобы быть копией дескриптора выходного файлаy
.1
Дескриптор выходного файла « Стандартный вывод ».Выражение
2>&1
копирует файловый дескриптор1
в местоположение2
, поэтому любой вывод, записанный в2
(«стандартная ошибка») в среде выполнения, попадает в тот же файл, который первоначально был описан1
(«стандартный вывод»).Дальнейшее объяснение:
Дескриптор файла : «Уникальное неотрицательное целое число для каждого процесса, используемое для идентификации открытого файла с целью доступа к файлу».
Стандартный вывод / ошибка : см. Следующее примечание в разделе « Перенаправление » документации оболочки:
источник
2 - стандартная ошибка консоли.
1 - стандартный вывод консоли.
Это стандартный Unix, и Windows также следует POSIX.
Например, когда вы бежите
стандартная ошибка перенаправляется на стандартный вывод, поэтому вы можете видеть оба выхода вместе:
После выполнения вы можете увидеть все выходные данные, включая ошибки, в файле debug.log.
Затем стандартный вывод идет в out.log, а стандартная ошибка в err.log.
Я предлагаю вам попытаться понять это.
источник
perl test.pl > debug.log 2>&1
Чтобы ответить на ваш вопрос: он берет любой вывод ошибок (обычно отправляется в stderr) и записывает его в стандартный вывод (stdout).
Это полезно, например, для «more», когда вам требуется подкачка для всего вывода. Некоторые программы любят печатать информацию об использовании в stderr.
Чтобы помочь вам вспомнить
«2> & 1» просто указывает все, что отправлено на stderr, вместо этого на stdout.
Я также рекомендую прочитать этот пост о перенаправлении ошибок, где эта тема покрыта в деталях.
источник
С точки зрения программиста, это означает именно это:
Смотрите справочную страницу .
Понимание того, что
2>&1
это копия, также объясняет, почему ...... это не то же самое, что ...
Первый отправит оба потока в
file
, а второй отправит ошибкиstdout
и обычный вывод вfile
.источник
Я нашел это очень полезным, если вы новичок, прочитайте это
Обновление:
в Linux или Unix System есть два места, куда программы отправляют вывод: Стандартный вывод (stdout) и Стандартная ошибка (stderr). Вы можете перенаправить эти выходные данные в любой файл.
Например, если вы сделаете это,
ls -a > output.txt
ничего не будет напечатано в консоли, все выходные данные (stdout) перенаправляются в выходной файл.
И если вы попытаетесь распечатать содержимое любого файла, который не выходит, это означает, что вывод будет с ошибкой, как если бы вы распечатали test.txt, которого нет в текущем каталоге.
cat test.txt > error.txt
Вывод будет
Но файл error.txt будет пустым, потому что мы перенаправили stdout в файл, а не в stderr.
поэтому нам нужен дескриптор файла (дескриптор файла - не более чем положительное целое число, представляющее открытый файл. Вы можете сказать, дескриптор - это уникальный идентификатор файла), чтобы указать оболочке, какой тип вывода мы отправляем в файл. В системе Unix / Linux 1 для стандартного вывода и 2 для стандартного ввода .
так что теперь, если вы делаете это,
ls -a 1> output.txt
значит, вы отправляете стандартный вывод (stdout) в output.txt.и если вы делаете это,
cat test.txt 2> error.txt
значит, вы отправляете стандартную ошибку (stderr) в error.txt.&1
используется для ссылки на значение дескриптора файла 1 (стандартный вывод).Теперь к сути
2>&1
означает «Перенаправить stderr в то же место, где мы перенаправляем стандартный вывод»Теперь вы можете сделать это
cat maybefile.txt > output.txt 2>&1
и стандартный вывод (stdout), и стандартная ошибка (stderr) будут перенаправлены в output.txt.
Спасибо Ондрей К. за указание
источник
Люди, всегда помните paxdiablo намек «s о текущем местоположении цели Перенаправление ... Это является важным.
Моя личная мнемоника для
2>&1
оператора такова:&
как это означает'and'
или'add'
(персонаж Н. ampers - и , не так ли?)2
(stderr) туда, где1
(stdout) уже / в настоящее время и добавить оба потока» .Та же самая мнемоника работает и для других часто используемых перенаправлений
1>&2
:&
значенииand
илиadd
... (вы поняли насчет амперсанда, да?)1
(stdout) туда, где2
(stderr) уже / в настоящее время и добавить оба потока» .И всегда помните: вы должны читать цепочки перенаправлений «с конца», справа налево ( не слева направо).
источник
Ref:
Введите,
/^REDIRECT
чтобы найти вredirection
разделе, и узнать больше ...Онлайн версия здесь: 3.6 Перенаправления
PS:
Много времени
man
было мощным инструментом для изучения Linux.источник
При условии, что
/foo
не существует в вашей системе и/tmp
…распечатает содержимое
/tmp
и напечатает сообщение об ошибке для/foo
отправит содержимое
/tmp
в/dev/null
и напечатает сообщение об ошибке для/foo
будет делать то же самое (обратите внимание на 1 )
распечатает содержимое
/tmp
и отправит сообщение об ошибке/dev/null
отправит как список, так и сообщение об ошибке
/dev/null
это стенография
источник
Это похоже на передачу ошибки на стандартный вывод или в терминал.
То есть
cmd
не команда:Ошибка отправляется в файл следующим образом:
Стандартная ошибка отправляется на терминал.
источник
0 для ввода, 1 для стандартного вывода и 2 для стандартного ввода.
Один совет :
somecmd >1.txt 2>&1
правильно, ноsomecmd 2>&1 >1.txt
совершенно неправильно без эффекта!источник
unix_commands 2>&1
Это используется для печати ошибок в терминал.
Следующее иллюстрирует процесс
&2
«буфер», из которого2
ссылается стандартный поток ошибок .&1
«буфер», из которого1
ссылается стандартный поток вывода .Поэтому возьмите
unix_commands
стандартный поток ошибок2
и перенаправьте>
поток (ошибок) на стандартный адрес памяти вывода&1
, чтобы они были переданы на терминал и распечатаны.источник