Почему перенаправление STDERR в / dev / null осуществляется таким образом?

29

Это не имеет смысла для меня.

wibble > /dev/null 2>&1

Я думаю, что было бы больше смысла, если бы это было что-то вроде этого:

wibble 2>&1 > /dev/null

Другими словами

Commands Output Sendall STDERRORS to STDOUT then SEND it all to /dev/null

Что стоит за порядком перенаправления команд xxx > /dev/null 2>1?

кто я
источник
6
Вы также можете найти это объяснение полезным.
rozcietrzewiacz
Спасибо @rozcietzewiacz, который на самом деле точно объясняет мой вопрос
whoami
1
В середине этой страницы есть отличный отрывок из Wiki Грега: «Если вы все еще не уверены в этом, это, вероятно, потому, что вы начали с неправильного представления о том, как работают FD, и вы не смогли отбросить это заблуждение. еще. Не волнуйтесь - это очень распространенное заблуждение, и вы не одиноки. … Многие люди думают, что 2>&1каким- то образом «объединяет» или «связывает вместе», или «женится» на двух FD, так что любое [последующее] изменение одного из них становится изменением другого. Это не тот случай. »
G-Man говорит:« Восстановите Монику »

Ответы:

41

Перенаправления обрабатываются слева направо. Если вы делаете

2>&1 1> /dev/null

Первое перенаправление stderrуказывает на поток, который stdoutуказывает на это время (что по сути является вашим tty). Это не делает stderrпсевдоним stdout.

Затем stdoutперенаправляется на ведро бит. stdoutРедирект не влияет на предыдущий stderrредирект. stderrвсе еще относится к вашему tty.

Так:

ls file_that_doesnt_exist 2>&1 1> /dev/null

напечатает только сообщение об ошибке на вашем терминале.

На bashстранице документации по перенаправлению прямо упоминается:

Обратите внимание, что порядок перенаправлений является значительным. Например, команда

          ls > dirlist 2>&1

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

          ls 2>&1 > dirlist

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

Мат
источник
3
Yay решает мою головоломку. Я все еще думаю, что логически это сбивает с толку. но я нашел другую часть на той же странице, которая интересна &>/dev/nullсемантически эквивалентна/dev/null 2>&1
whoami
1
Следует подчеркнуть, что страница, о которой вы говорите, является частью справочного руководства Bash . Это, очевидно, описывает bash . В мире существуют другие оболочки, отличные от bash, и &>и >&(когда они не используются в контексте 2>&1или >&2и т. Д.) Представляют собой bash-isms и не являются стандартными . Они не должны использоваться в сценариях оболочки, которые вы хотите переносить.
G-Man говорит: «Восстановите Монику»