Order of redirections
I find it easier to think of using assignments.
>
is like=
&
is like$
You start out with
1 = /dev/tty
2 = /dev/tty
then your first example, 1> file.txt 2>&1
, does
1 = file.txt
2 = $1 # and currently $1 = file.txt
leaving you with
1 = file.txt
2 = file.txt
If you did it the other way, again you start with
1 = /dev/tty
2 = /dev/tty
then 2>&1 > file.txt
does
2 = $1 # and currently $1 = /dev/tty
1 = file.txt
so the end result is
1 = file.txt
2 = /dev/tty
and you've only redirected stdout
, not stderr
.
The order of redirection is important, and they should be read left to right.
For example:
command 2>&1 >somefile
means:
- Redirect the descriptor named
2
(bound tostderr
) to the current destination of1
(stdout
) which at this point, reading left-ot-right is the terminal. - Then change
1
(stdout
) to go tosomefile
, which is a a file in disk
So in this case, stderr
goes to the terminal, and stdout
goes to a file, which isn't what you probably want.
On the other hand, command >somefile 2>&1
means:
- Redirect
stdout
tosomefile
- Then redirect
stderr
to the same destination asstdout
(somefile
).
In this last case both stderr
and stdout
go to somefile
, which is probably what you want.
cat file1 file2 1> file.txt 2>&1
>&
Actually means duplicate, it uses the dup system call to to map a new file descriptor onto an already opened file.
So, you (bash actually) must first open the new stdout before, saying " and redirect stderr to whatever stdout is currently set."