Что в оболочке означает 2 ›и 1?

В оболочке Unix, если я хочу объединить stderr и stdout в поток stdout для дальнейших манипуляций, я могу добавить следующее в конце моей команды:

2>&1

Итак, если я хочу использовать head на выходе из g++, я могу сделать что-то вроде этого:

g++ lots_of_errors 2>&1 | head

поэтому я вижу только несколько первых ошибок.

Мне всегда трудно это запоминать, и мне постоянно приходится искать это, в основном потому, что я не полностью понимаю синтаксис этого конкретного трюка.

Может ли кто-нибудь разбить это на части и по характеру объяснить, что означает 2>&1?


person Tristan Havelick    schedule 03.05.2009    source источник
comment
@dbr Я не думаю, что это просто bash - я считаю, что это вещь оболочки Борна; отсюда sh, bash, ksh, ash, dash и т. д.   -  person guns    schedule 04.05.2009
comment
Это часть параграфа перенаправления, описывающего POSIX-совместимые оболочки, или для краткости POSIX shell. ksh - это, например, оболочка POSIX. См. pubs.opengroup.org/onlinepubs/009695399/utilities/   -  person jim mcnamara    schedule 04.04.2013
comment
Эта конструкция также работает в Windows.   -  person Vadzim    schedule 22.10.2013
comment
Обычно лучше делать 2>&1, чем 2 ›/ dev / null ;-)   -  person F. Hauri    schedule 08.12.2013
comment
Я подумал, что стоит упомянуть, что |& - это сокращение от 2>&1 |, если вы используете zsh. Я не могу сказать, относится ли это к другим оболочкам, подобным Bourne, или это только функция zsh.   -  person chrixian    schedule 17.12.2013
comment
@chrixian |& также есть в Bash, отличная функция. Не POSIX кажется, хотя (?)   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 27.07.2015
comment
вы можете проверить этот ответ https://stackoverflow.com/questions/10508843/what-is-dev-null-21/42919998#answer-42919998   -  person Vishrant    schedule 19.07.2018


Ответы (18)


Дескриптор файла 1 - это стандартный вывод (stdout).
Дескриптор файла 2 - это стандартная ошибка (stderr).

Вот один из способов запомнить эту конструкцию (хотя он не совсем точен): сначала 2>1 может показаться хорошим способом перенаправить stderr на stdout. Однако на самом деле это будет интерпретироваться как перенаправление stderr в файл с именем 1. & указывает, что то, что следует и предшествует, является дескриптором файла, а не именем файла. Таким образом, конструкция становится: 2>&1.

Считайте >& оператором слияния с перенаправлением.

person Ayman Hourieh    schedule 03.05.2009
comment
имеет ли это какое-то значение для вас, java... 2&1 >> data.log, я видел, как это сделал один из моих коллег? - person Thang Pham; 26.07.2011
comment
›› означает добавление вывода в файл data.log. - person Khue Vu; 12.11.2011
comment
@ThangPham означает, что STDOUT добавлен в data.log и STDERR выгружен в STDOUT (консоль или следующая команда) см. Мой ответ - person F. Hauri; 17.01.2013
comment
Мне это кажется точным. Как это «не совсем точно»? - person Bad Request; 03.07.2013
comment
но тогда разве это не должно быть &2>&1? - person dokaspar; 04.09.2013
comment
@Dominik: Нет, & интерпретируется только как обозначение дескриптора файла в контексте перенаправлений. Запись command &2>& анализируется как command & и 2>&1, т.е. запускать command в фоновом режиме, затем запускать команду 2 и перенаправлять ее стандартный вывод в свой стандартный вывод. - person Adam Rosenfield; 28.01.2014
comment
Почему они выбрали такие загадочные вещи? Просто любопытно. - person CommaToast; 17.05.2014
comment
Но как бы вы перенаправили stderr в файл с именем '& 1'? - person Martín Fixman; 04.11.2014
comment
@ Мартин: 2>'&1' - person ; 14.03.2016
comment
любая идея, почему это взаимодействует с выделением grep? nginx -V 2>&1 | grep auth_request, выделяет слово auth_request красным, а nginx -V | grep auth_request - нет - person JonnyRaa; 28.09.2017
comment
так что & значения дескриптора файла, а также перейти в фоновый режим ?? Linux нужно перестать использовать один и тот же символ, который слишком сбивает с толку !! - person bakalolo; 11.01.2018
comment
В случае, если это помогает кому-то в мнемонике, то, как я думаю об этом, связано с оператором & языка Си, адресом - так что 2>&1 в целом я читаю в своей голове как что-то похожее на (дескриптор файла) 2, перенаправляет на адрес (дескриптор файла) 1. Т.е. туда, куда сейчас идет fd1, на момент чтения оболочкой этой 4-символьной последовательности. (Потому что это может измениться. Ради интереса попробуйте: ((echo 1/stdout; echo 2/stderr >&2) 2>&1 > /dev/tty) | grep --color . - он раскрасит то, что начиналось как стандартная ошибка (2 / stderr).) - person lindes; 05.05.2018
comment
Что произойдет, если я сделаю 2> &1 (пробел после >) вместо 2>&1? Я сам не пробую из-за страха сломать вещи. - person radiantshaw; 26.08.2018
comment
@radiantshaw Просто выдает сообщение об ошибке. В bash: foo 2>&1 выводит -bash: foo: command not found, а foo 2> &1 выводит -bash: синтаксическая ошибка рядом с неожиданным токеном '&'. Оболочки часто придирчивы к пробелам вокруг символов. @Aaron Franke Да, foo 2>\&1 создает новый файл с именем & 1, содержащий вышеуказанный текст ошибки. - person Beejor; 05.05.2019
comment
почему ты сказал, что это не совсем верно? Какую деталь вы перепрыгнули? - person Fakher Mokadem; 13.10.2019
comment
Re Почему они выбрали такие загадочные вещи?, действительно хорошо использовать связанные токены для связанных вещей. В bash < перенаправляет из файла; <& перенаправляет с fd; <<... перенаправляет из документа, <(...) перенаправляет из процесса; и <<< ... перенаправляет из строкового литерала. - person ikegami; 09.05.2020
comment
@CommaToast Точно. Все говорят мне, что магические константы плохо программируют, избегайте их, используйте вместо них имена. И у нас есть жестко запрограммированные целые числа файловых дескрипторов в ядре операционной системы. Як. Почему они не могли просто использовать такие ключевые слова, как stderr > stdout? Еще одно несоответствие - > обычно означает заменить. Итак, 2>&1 можно спутать с заменой всего вывода на вывод ошибок. Почему бы не использовать >> для добавления, как мы это делаем для файлов? Итак, я голосую за stderr >> stdout. - person JustAMartin; 04.09.2020
comment
@CommaToast То же самое можно сказать и о любых операциях оболочки. Тайные символы, перегруженные операторы, однобуквенные флаги ... - person user3932000; 10.10.2020
comment
В качестве мнемоники, если вы знаете C, следуя арифметике указателей, вы можете думать об этом как о содержимом 2 (2) go (>) туда, где 1, то есть в адрес памяти, равный 1 (&1 ). - person xmar; 25.11.2020

echo test > afile.txt

перенаправляет стандартный вывод на afile.txt. Это то же самое, что и делать

echo test 1> afile.txt

Чтобы перенаправить stderr, вы:

echo test 2> afile.txt

>& - это синтаксис для перенаправления потока на другой дескриптор файла: 0 - это стандартный ввод, 1 - стандартный вывод и 2 - стандартный поток.

Вы можете перенаправить stdout на stderr, выполнив:

echo test 1>&2 # or echo test >&2

Или наоборот:

echo test 2>&1

Итак, вкратце ... 2> перенаправляет stderr в (неуказанный) файл, добавление &1 перенаправляет stderr в stdout.

person dbr    schedule 03.05.2009
comment
имеет ли это какое-то значение для вас, java ... 2&1 >> data.log, я видел, как это сделал один из моих коллег? - person Thang Pham; 26.07.2011
comment
@Harry, который выглядит как оболочка, отличная от bash, или опечатка .. cmd 2>&1 >> somefile.log добавит stdout / stderr к файлу - это в основном то же самое, что и выше, с >> file для добавления - person dbr; 27.07.2011
comment
@dbr cmd 2>&1 >>file не перенаправляет stderr в файл, но cmd >> file 2>&1 делает. Порядок имеет значение. В первом случае stderr перенаправляется на стандартный вывод оболочки (возможно, на tty, если команда вводится в интерактивном режиме), а затем стандартный вывод направляется в файл. Во втором случае stdout направляется в файл, а затем stderr направляется в то же место. - person William Pursell; 19.07.2013
comment
Мне нравится ответ выше, но он мог бы быть более ясным. 2 ›& 1 перенаправляет stderr на цель stdout. Итак, если у вас есть что-то вроде ls -l ›› directoryContents 2 ›& 1, результатом будет файл с именем directoryContents, к которому будет добавлено содержимое рабочего каталога. Если при выполнении возникают какие-либо ошибки: сообщения об ошибках также будут добавлены в файл directoryContents по мере их возникновения. - person Max West; 17.04.2015
comment
0(or 1,2)>&0(or 1,2) как вариант управления выводом? echo test >test.log 2>&1 то же самое, что echo test 2>&1 >test.log? - person Simin Jie; 01.06.2018

Некоторые хитрости с перенаправлением

Некоторые особенности синтаксиса могут иметь важные особенности. Вот несколько примеров переадресации, STDERR, STDOUT и порядка аргументов.

1 - перезапись или добавление?

Символ > означает перенаправление.

  • > означает отправить в весь завершенный файл, перезаписывая целевой объект, если он существует (см. noclobber функцию bash в №3 позже).
  • >> означает, что отправить в дополнение к будет добавляться к цели, если она существует.

В любом случае файл будет создан, если они не существуют.

2 - Командная строка оболочки зависит от порядка !!

Для тестирования нам нужна простая команда, которая будет отправлять что-то на оба выхода:

$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

(Конечно, ожидая, что у вас нет каталога с именем /tnt;). Что ж, оно у нас есть !!

Итак, посмотрим:

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1

$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory

Последняя командная строка выгружает STDERR в консоль, и это, похоже, не соответствует ожидаемому поведению ... Но ...

Если вы хотите выполнить фильтрацию сообщений для стандартного вывода, ошибки вывода или того и другого:

$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'

$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->

Обратите внимание, что последняя командная строка в этом абзаце точно такая же, как и в предыдущем абзаце, где я написал , похоже, не является ожидаемым поведением (так что это может быть даже ожидаемым поведением).

Что ж, есть небольшие уловки с перенаправлением для выполнения разных операций на обоих выходах:

$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2  2>&1  | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan  7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory

Примечание: дескриптор &9 возникнет спонтанно из-за ) 9>&2.

Дополнение: примечание! В новой версии bash (>4.0) есть новая функция и более привлекательный синтаксис для выполнения таких действий:

$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory

И, наконец, для такого каскадного форматирования вывода:

$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
     1  O: drwxrwxrwt 118 root root 196608 Jan  7 12:29 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

Дополнение: примечание! Одинаковый новый синтаксис в обоих направлениях:

$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
     1  O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

Где STDOUT проходят через определенный фильтр, STDERR - через другой, и, наконец, оба объединенных выхода проходят через третий фильтр команд.

3 - Несколько слов о параметре noclobber и синтаксисе >|

Это о перезаписи:

В то время как set -o noclobber предписывает bash не перезаписывать существующие файлы, >| синтаксис позволяет обойти это ограничение:

$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:15 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:19 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:21 CET 2013

Файл каждый раз перезаписывается, ну а теперь:

$ set -o noclobber

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

Пройдите с >|:

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:18:58 CET 2013

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:19:01 CET 2013

Отключение этой опции и / или запрос, если он уже установлен.

$ set -o | grep noclobber
noclobber           on

$ set +o noclobber

$ set -o | grep noclobber
noclobber           off

$ date > $testfile ; cat $testfile
Mon Jan  7 13:24:27 CET 2013

$ rm $testfile

4 - Последний трюк и многое другое ...

Для перенаправления обоих выходных данных заданной команды мы видим, что правильный синтаксис может быть таким:

$ ls -ld /tmp /tnt >/dev/null 2>&1

для этого особого случая существует сокращенный синтаксис: &> ... или >&

$ ls -ld /tmp /tnt &>/dev/null

$ ls -ld /tmp /tnt >&/dev/null

Примечание: если 2>&1 существует, 1>&2 также является правильным синтаксисом:

$ ls -ld /tmp /tnt 2>/dev/null 1>&2

4b- Теперь я позволю вам подумать о:

$ ls -ld /tmp /tnt 2>&1 1>&2  | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

$ ls -ld /tmp /tnt 1>&2 2>&1  | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

4c- Если вас интересует дополнительная информация

Вы можете прочитать прекрасное руководство, нажав:

man -Len -Pless\ +/^REDIRECTION bash

в консоли bash ;-)

person F. Hauri    schedule 29.04.2013
comment
Дополнительная литература: Если вам это понравилось, вы можете оценить: Как злоупотребление перенаправлением может привести к странному поведению - person F. Hauri; 11.12.2013
comment
Дополнительная литература ||: функция для хранения обоих выходных данных в отдельных переменных - person F. Hauri; 18.01.2015

Я нашел этот замечательный пост о перенаправлении: Все о перенаправлениях

Перенаправить в файл как стандартный вывод, так и стандартную ошибку

$ команда &> файл

Этот однострочник использует оператор &> для перенаправления обоих выходных потоков - stdout и stderr - от команды к файлу. Это ярлык Bash для быстрого перенаправления обоих потоков в одно и то же место назначения.

Вот как выглядит таблица дескрипторов файлов после того, как Bash перенаправил оба потока:

Введите описание изображения здесь

Как видите, и stdout, и stderr теперь указывают на file. Таким образом, все, что написано в stdout и stderr, записывается в file.

Есть несколько способов перенаправить оба потока в одно и то же место назначения. Вы можете перенаправлять каждый поток один за другим:

$ команда> файл 2> & 1

Это гораздо более распространенный способ перенаправления обоих потоков в файл. Сначала stdout перенаправляется в файл, а затем stderr дублируется, чтобы быть таким же, как stdout. Таким образом, оба потока в конечном итоге указывают на file.

Когда Bash видит несколько перенаправлений, он обрабатывает их слева направо. Давайте пройдемся по шагам и посмотрим, как это произойдет. Перед запуском любых команд таблица файловых дескрипторов Bash выглядит следующим образом:

Введите здесь описание изображения

Теперь Bash обрабатывает первый файл перенаправления>. Мы видели это раньше, и это указывает на то, что stdout указывает на файл:

Введите описание изображения здесь

Далее Bash видит второе перенаправление 2> & 1. Раньше мы не видели этого перенаправления. Он дублирует файловый дескриптор 2, чтобы быть копией файлового дескриптора 1, и мы получаем:

Введите описание изображения здесь

Оба потока перенаправлены в файл.

Однако будьте здесь осторожны! Пишу

команда> файл 2> & 1

это не то же самое, что писать:

$ команда 2> & 1> файл

Порядок перенаправления имеет значение в Bash! Эта команда перенаправляет в файл только стандартный вывод. Stderr по-прежнему будет печатать на терминал. Чтобы понять, почему это происходит, давайте еще раз пройдемся по шагам. Итак, перед запуском команды таблица файловых дескрипторов выглядит так:

Введите здесь описание изображения

Теперь Bash обрабатывает перенаправления слева направо. Сначала он видит 2> & 1, поэтому дублирует stderr на stdout. Таблица файловых дескрипторов становится:

Введите здесь описание изображения

Теперь Bash видит второе перенаправление, >file, и перенаправляет стандартный вывод в файл:

Введите здесь описание изображения

Вы видите, что здесь происходит? Stdout теперь указывает на файл, но stderr по-прежнему указывает на терминал! Все, что записывается в stderr, по-прежнему выводится на экран! Так что будьте очень и очень осторожны с порядком переадресации!

Также обратите внимание, что в Bash написание

$ команда &> файл

точно так же, как:

$ команда> & файл

person Deen John    schedule 29.10.2016
comment
Последние два различаются, если команда заканчивается числом, так как тогда это считается необязательным файловым дескриптором для >&. - person M.M; 23.01.2017
comment
Очень красивый рисунок и объяснение! Не могли бы вы пояснить, что на самом деле означает дубликат? Вы упомянули, что этот [2 ›& 1] дублирует файловый дескриптор 2, чтобы быть копией файлового дескриптора 1. Похоже, что stderr дублируется в stdout. Но если это так, должен ли я также видеть ошибку /dev/tty0? - person HCSF; 22.07.2019
comment
Это очень хорошее наглядное объяснение. Если я стал тем, кто задает этот вопрос, я отмечу это как принятый ответ. - person MaXi32; 18.10.2020

Цифры относятся к дескрипторам файлов (fd).

  • Ноль - это stdin
  • Один stdout
  • Два stderr

2>&1 перенаправляет fd 2 на 1.

Это работает для любого количества файловых дескрипторов, если программа их использует.

Вы можете посмотреть /usr/include/unistd.h, если забудете их:

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */

Тем не менее, я написал инструменты C, которые используют нестандартные файловые дескрипторы для пользовательского ведения журнала, поэтому вы не увидите его, если не перенаправите его в файл или что-то в этом роде.

person Colin Burnett    schedule 03.05.2009

Эта конструкция отправляет стандартный поток ошибок (stderr) в текущее расположение стандартного вывода (stdout) - эта проблема с валютой, похоже, не учитывалась другими ответами.

Вы можете перенаправить любой дескриптор вывода на другой с помощью этого метода, но чаще всего он используется для направления потоков stdout и stderr в один поток для обработки.

Вот несколько примеров:

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

Обратите внимание, что последний не перенаправляет stderr на outfile2 - он перенаправляет его на то, что было stdout, когда был обнаружен аргумент (outfile1), а затем перенаправляет stdout на outfile2.

Это позволяет использовать довольно изощренные уловки.

person paxdiablo    schedule 03.05.2009
comment
Хотя последний пример был бы намного понятнее: foo ›outfile2 2› outfile1 - person Michael Cramer; 04.05.2009
comment
Яснее, да, но это не показывает позиционный характер перенаправления. Пример надуманный, поскольку обычно нецелесообразно делать это в одной строке - метод становится действительно полезным, когда разные стороны несут ответственность за разные части перенаправления. Например, когда сценарий выполняет один бит перенаправления, а вы запускаете его с другим битом. - person paxdiablo; 04.05.2009
comment
Я только что понял, что последний пример также разрешает давнюю путаницу, которую я имел относительно того, почему это: some_program 2>&1 > /dev/null не работает так: some_program > /dev/null 2>&1. - person snapfractalpop; 20.12.2012
comment
Ваш комментарий о последнем примере стоит своих золотых букв :-) Я никогда не думал, что эти аргументы перенаправления позиционны ... Я думаю, что это очень важно знать. - person Nils-o-mat; 18.04.2018

Я нашел это очень полезным, если вы новичок, прочтите это

Обновление:
В системе Linux или Unix есть два места, куда программы отправляют вывод: стандартный вывод (stdout) и стандартная ошибка (stderr). Вы можете перенаправить этот вывод в любой файл.

Как, если вы это сделаете

ls -a > output.txt

Ничего не будет напечатано в консоли, весь вывод (stdout) перенаправляется в выходной файл.

И если вы попытаетесь распечатать содержимое любого файла, который не завершается, это означает, что вывод будет с ошибкой, как если бы вы распечатали test.txt, которого нет в текущем каталоге

cat test.txt > error.txt

Вывод будет

cat: test.txt :No such file or directory

Но файл error.txt будет пустым, потому что мы перенаправляем stdout в файл, а не в stderr.

поэтому нам нужен дескриптор файла (дескриптор файла - это не что иное, как положительное целое число, которое представляет открытый файл. Вы можете сказать, что дескриптор - это уникальный идентификатор файла), чтобы сообщить оболочке, какой тип вывода мы отправляем в файл . В системе Unix / Linux 1 для stdout и 2 для stderr.

так что теперь, если вы это сделаете

ls -a 1> output.txt означает, что вы отправляете стандартный вывод (stdout) в output.txt.

и если вы это сделаете

cat test.txt 2> error.txt означает, что вы отправляете стандартную ошибку (stderr) в error.txt.

&1 используется для ссылки на значение файлового дескриптора 1 (stdout).

Теперь перейдем к делу 2>&1 означает «Перенаправить stderr в то же место, где мы перенаправляем stdout»

Теперь вы можете это сделать
‹br

cat maybefile.txt > output.txt 2>&1

стандартный вывод (stdout) и стандартный вывод ошибок (stderr) будут перенаправлены на output.txt.

Спасибо Ондрею К. за указание

person kundan bora    schedule 01.04.2020
comment
Ответы только по ссылкам проблематичны. Ссылка может перестать существовать, и ответ станет бесполезным. Вы всегда должны включать достаточно подробностей в сам ответ. - person Ondrej K.; 01.04.2020

2 - стандартная ошибка консоли.

1 - стандартный вывод консоли.

Это стандартный Unix, и Windows также следует POSIX.

Например. когда ты бежишь

perl test.pl 2>&1

стандартная ошибка перенаправляется на стандартный вывод, поэтому вы можете видеть оба вывода вместе:

perl test.pl > debug.log 2>&1

После выполнения вы можете увидеть весь вывод, включая ошибки, в debug.log.

perl test.pl 1>out.log 2>err.log

Затем стандартный вывод идет в out.log, а стандартная ошибка - в err.log.

Предлагаю вам попытаться понять это.

person Marcus Thornton    schedule 19.07.2013
comment
Второй пример неверен: поскольку приоритет порядка STDERR перенаправляется на STDOUT, только STDOUT по умолчанию будет записан в debug.log < / i> (не STDERR) см. мой ответ (абзац №2)! Чтобы обеспечить перенаправление обоих в один и тот же файл, необходимо инвертировать директивы перенаправления: perl test.pl > debug.log 2>&1 - person F. Hauri; 10.02.2015

2>&1 - это конструкция оболочки POSIX. Вот разбивка по токенам:


2: дескриптор выходного файла "Стандартная ошибка".

>&: Дублировать дескриптор выходного файла оператор (вариант Перенаправление вывода оператор >). Учитывая [x]>&[y], дескриптор файла, обозначенный x, делается копией дескриптора выходного файла y.

1 Дескриптор выходного файла "Стандартный вывод".

Выражение 2>&1 копирует файловый дескриптор 1 в расположение 2, поэтому любой вывод, записанный в 2 («стандартная ошибка») в среде выполнения, попадает в тот же файл, который изначально описан в 1 («стандартный вывод»).


Дальнейшее объяснение:

Дескриптор файла: "За -процесс - уникальное неотрицательное целое число, используемое для идентификации открытого файла с целью доступа к файлу. "

Стандартный вывод / ошибка: см. следующее примечание в Перенаправление документации оболочки:

Открытые файлы представлены десятичными числами, начинающимися с нуля. Максимально возможное значение определяется реализацией; однако все реализации должны поддерживать как минимум от 0 до 9 включительно для использования приложением. Эти числа называются «файловыми дескрипторами». Значения 0, 1 и 2 имеют особое значение и обычное использование и подразумеваются определенными операциями перенаправления; они называются стандартным вводом, стандартным выводом и стандартной ошибкой соответственно. Программы обычно получают ввод со стандартного ввода и записывают вывод на стандартный вывод. Сообщения об ошибках обычно пишутся о стандартных ошибках. Операторам перенаправления может предшествовать одна или несколько цифр (без использования промежуточных символов) для обозначения номера дескриптора файла.

person wjordan    schedule 25.12.2016

Чтобы ответить на ваш вопрос: он принимает любой вывод ошибки (обычно отправляется на stderr) и записывает его на стандартный вывод (stdout).

Это полезно, например, с "more", когда вам нужно разбивать на страницы весь вывод. Некоторые программы, например, выводят информацию об использовании в stderr.

Чтобы помочь тебе запомнить

  • 1 = стандартный вывод (где программы печатают нормальный вывод)
  • 2 = стандартная ошибка (когда программы печатают ошибки)

«2> & 1» просто указывает все, что отправлено на stderr, вместо этого на stdout.

Я также рекомендую прочитать этот пост об ошибке перенаправления, где рассматривается эта тема в полной мере.

person Andrioid    schedule 03.05.2009

С точки зрения программиста это означает именно это:

dup2(1, 2);

См. справочную страницу.

Понимание того, что 2>&1 является копией, также объясняет, почему ...

command >file 2>&1

... не то же самое, что ...

command 2>&1 >file

Первый отправляет оба потока в file, тогда как второй отправляет ошибки в stdout, а обычный вывод - в file.

person ams    schedule 03.12.2015

Люди, всегда помните намек paxdiablo о текущем местоположении цели перенаправления ... Это важно.

Моя личная мнемоника для оператора 2>&1 такова:

  • Думайте о & как о значении 'and' или 'add' (символ - это амперы - и, не так ли?)
  • Таким образом, получается: «перенаправить 2 (stderr) туда, где 1 (stdout) уже / в настоящее время находится и добавить оба потока».

Та же мнемоника работает и для другого часто используемого перенаправления 1>&2:

  • Подумайте о &, означающем and или _10 _... (вы поняли, что такое амперсанд, да?)
  • Таким образом, он становится: «перенаправить 1 (stdout) туда, где 2 (stderr) уже / в настоящее время находится и добавить оба потока».

И всегда помните: цепочки перенаправлений нужно читать «с конца», справа налево (не слева направо).

person Kurt Pfeifle    schedule 01.07.2012

Перенаправление ввода

Перенаправление ввода заставляет файл, имя которого является результатом раскрытия слова, открываться для чтения в файловом дескрипторе n или в стандартном вводе (файловый дескриптор 0), если n не указано.

Общий формат перенаправления ввода:

[n]<word

Перенаправление вывода

Перенаправление вывода приводит к открытию файла, имя которого является результатом раскрытия слова, для записи в файловый дескриптор n или стандартный вывод (файловый дескриптор 1), если n не указано. Если файл не существует, он создается; если он существует, он обрезается до нулевого размера.

Общий формат перенаправления вывода:

[n]>word

Перемещение файловых дескрипторов

Оператор перенаправления,

[n]<&digit-

перемещает цифру файлового дескриптора в файловый дескриптор n или на стандартный ввод (файловый дескриптор 0), если n не указано. цифра закрывается после дублирования на n.

Аналогично оператор перенаправления

[n]>&digit-

перемещает цифру файлового дескриптора в файловый дескриптор n или в стандартный вывод (файловый дескриптор 1), если n не указано.

Ссылка:

man bash

Введите /^REDIRECT, чтобы перейти в раздел redirection и узнать больше ...

Онлайн-версия находится здесь: 3.6 Перенаправления

PS:

В большинстве случаев man был мощным инструментом для изучения Linux.

person yurenchen    schedule 06.06.2015

При условии, что /foo не существует в вашей системе, а /tmp существует…

$ ls -l /tmp /foo

распечатает содержимое /tmp и сообщение об ошибке для /foo

$ ls -l /tmp /foo > /dev/null

отправит содержимое /tmp на /dev/null и распечатает сообщение об ошибке для /foo

$ ls -l /tmp /foo 1> /dev/null

будет делать то же самое (обратите внимание на 1)

$ ls -l /tmp /foo 2> /dev/null

распечатает содержимое /tmp и отправит сообщение об ошибке /dev/null

$ ls -l /tmp /foo 1> /dev/null 2> /dev/null

отправит листинг и сообщение об ошибке на /dev/null

$ ls -l /tmp /foo > /dev/null 2> &1

стенография

person Matijs    schedule 01.09.2016

Это похоже на передачу ошибки в stdout или терминал.

То есть cmd не является командой:

$cmd 2>filename
cat filename

command not found

Ошибка отправляется в файл следующим образом:

2>&1

На терминал отправляется стандартная ошибка.

person Kalanidhi    schedule 11.10.2013

unix_commands 2>&1

Это используется для вывода ошибок на терминал.

Ниже показан процесс

  • Когда возникают ошибки, они записываются в стандартный адрес памяти ошибок &2 "буфер", на который ссылается стандартный поток ошибок 2.
  • Когда производится вывод, он записывается в стандартный выходной адрес &1 "буфер" памяти вывода, на который ссылается стандартный выходной поток 1.

Итак, возьмите unix_commands стандартный поток ошибок 2 и перенаправьте > поток (ошибок) на стандартный адрес памяти вывода &1, чтобы они передавались на терминал и распечатывались.

person tim-montague    schedule 25.01.2020

0 для ввода, 1 для stdout и 2 для stderr.

Один совет: somecmd >1.txt 2>&1 правильно, а somecmd 2>&1 >1.txt полностью неверно и безрезультатно!

person ch271828n    schedule 25.07.2016

Обратите внимание, что 1>&2 не может использоваться взаимозаменяемо с 2>&1.

Представьте, что ваша команда зависит от конвейера, например:
docker logs 1b3e97c49e39 2>&1 | grep "some log"
grepping будет выполняться как для stderr, так и для stdout, поскольку stderr в основном объединяется с stdout.

Однако, если вы попытаетесь:
docker logs 1b3e97c49e39 1>&2 | grep "some log",
grepping вообще не будет искать нигде, потому что канал Unix соединяет процессы через соединение stdout | stdin, а stdout во втором случае был перенаправлен на stderr, в котором канал Unix не имеет интерес.

person yuranos    schedule 22.07.2020