shell standard streams redirection order OR 2>&1 1>/dev/null vs 1>/dev/null 2>&1

2716
Wakan Tanka

Can somebody please clarify differences? Is some of those considered as best practice? If I remember correct I somehow on SO read that this 1>/dev/null should precede this: 2>&1

ls -al /doesNotExists 2>&1 1>/dev/null ls -al /doesNotExists 1>/dev/null 2>&1 ls -al /doesNotExists 1>&2 2>/dev/null ls -al /doesNotExists 2>/dev/null 1>&2 ls -la /doesNotExists 2<&1 1>/dev/null ls -la /doesNotExists 2<&1 2>/dev/null ls -la /doesNotExists 1<&2 1>/dev/null ls -la /doesNotExists 1<&2 2>/dev/null ls -la /doesNotExists 1>/dev/null 2<&1 ls -la /doesNotExists 2>/dev/null 2<&1 ls -la /doesNotExists 1>/dev/null 1<&2 ls -la /doesNotExists 2>/dev/null 1<&2 
3
Прочитайте `n> & m` as, ** перенаправьте поток` n` туда, куда `m` в данный момент направлено **. Не перенаправить поток `n` в поток` m`. ctrl-alt-delor 9 лет назад 2
возможный дубликат [Что «2> & 1» делает в командной строке?] (http://superuser.com/questions/71428/what-does-21-do-in-command-line) Scott 9 лет назад 0

1 ответ на вопрос

6
DavidPostill

shell standard streams redirection order

The order matters as the outcome is different. Take your first example:

ls -al /doesNotExists 2>&1 1>/dev/null 

This directs only standard output to nul, because the standard error was duplicated to standard output before standard output was redirected to dirlist.

ls -al /doesNotExists 1>/dev/null 2>&1 

This directs both standard output and standard error to nul.


Bash Reference Manual: Redirections

Note that the order of redirections is significant. For example, the command

ls > dirlist 2>&1 

directs both standard output (file descriptor 1) and standard error (file descriptor 2) to the file dirlist, while the command

ls 2>&1 > dirlist 

directs only the standard output to file dirlist, because the standard error was made a copy of the standard output before the standard output was redirected to dirlist.

Source Bash Reference Manual: Redirections


Tutorial

There is a nice illustrated tutorial at Illustrated Redirection Tutorial which makes this easier to understand:

Order Of Redirection, i.e., "> file 2>&1" vs. "2>&1 >file"

While it doesn't matter where the redirections appears on the command line, their order does matter. They are setup from left to right.

2>&1 >file 

A common error, is to do command 2>&1 > file to redirect both stderr and stdout to file. Let's see what's going on. First we type the command in our typical terminal, the descriptors look like this:

 --- +-----------------------+ standard input ( 0 ) ---->| /dev/pts/5 | --- +-----------------------+ --- +-----------------------+ standard output ( 1 ) ---->| /dev/pts/5 | --- +-----------------------+ --- +-----------------------+ standard error ( 2 ) ---->| /dev/pts/5 | --- +-----------------------+ 

Then our shell, Bash sees 2>&1 so it duplicates 1, and the file descriptor look like this:

 --- +-----------------------+ standard input ( 0 ) ---->| /dev/pts/5 | --- +-----------------------+ --- +-----------------------+ standard output ( 1 ) ---->| /dev/pts/5 | --- +-----------------------+ --- +-----------------------+ standard error ( 2 ) ---->| /dev/pts/5 | --- +-----------------------+ 

That's right, nothing has changed, 2 was already pointing to the same place as 1. Now Bash sees > file and thus changes stdout:

 --- +-----------------------+ standard input ( 0 ) ---->| /dev/pts/5 | --- +-----------------------+ --- +-----------------------+ standard output ( 1 ) ---->| file | --- +-----------------------+ --- +-----------------------+ standard error ( 2 ) ---->| /dev/pts/5 | --- +-----------------------+ 

And that's not what we want.

>file 2>&1 

Now let's look at the correct command >file 2>&1. We start as in the previous example, and Bash sees > file:

 --- +-----------------------+ standard input ( 0 ) ---->| /dev/pts/5 | --- +-----------------------+ --- +-----------------------+ standard output ( 1 ) ---->| file | --- +-----------------------+ --- +-----------------------+ standard error ( 2 ) ---->| /dev/pts/5 | --- +-----------------------+ 

Then it sees our duplication 2>&1:

 --- +-----------------------+ standard input ( 0 ) ---->| /dev/pts/5 | --- +-----------------------+ --- +-----------------------+ standard output ( 1 ) ---->| file | --- +-----------------------+ --- +-----------------------+ standard error ( 2 ) ---->| file | --- +-----------------------+ 

And voila, both 1 and 2 are redirected to file.

Спасибо, хорошая графическая информация. Всего два уточнения: 1. `ls> / dev / null` это то же самое, что` ls 1> / dev / null` 2. Когда используется `<`? Я пробовал `ls -l> file & 1 <2`, и это не то же самое, что` ls> file 2> & 1`. Является ли `cat file` эквивалентным` cat Wakan Tanka 9 лет назад 0
@WakanTanka 1 / yes (1 означает только вывод std). 2 / <используется для перенаправления _input_ (файл cat совпадает с файлом cat <file) DavidPostill 9 лет назад 0
Когда полезно перенаправить ввод, он может открыть его, как я уже показал, зачем перенаправлять? Wakan Tanka 9 лет назад 0
Просто чтобы уточнить ответ в комментарии: `кошка Tiago 9 лет назад 0
Это объяснение очень приятно. Спасибо за диаграмму. Jingguo Yao 7 лет назад 0