ordem de redirecionamento de fluxos padrão do shell
A ordem é importante, pois o resultado é diferente. Tome seu primeiro exemplo:
ls -al /doesNotExists 2>&1 1>/dev/null
Isto direciona apenas a saída padrão para nul, porque o erro padrão foi duplicado para a saída padrão anterior a saída padrão foi redirecionada para a dirlist.
ls -al /doesNotExists 1>/dev/null 2>&1
Isso direciona a saída padrão e o erro padrão para nul.
Manual de Referência do Bash: Redirecionamentos
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.
Fonte Manual de referência do Bash: redirecionamentos
Tutorial
Há um belo tutorial ilustrado no Tutorial de Redirecionamento Ilustrado que torna isso mais fácil de entender:
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.