First, in a simple command (basically, the name of a program followed by some arguments), the relative position of arguments and redirections doesn't matter. You can even have redirections before the command name. The following are all equivalent:
foo --bar qux >out 2>err
foo >out --bar 2>err
>out 2>err foo --bar qux
(I won't list all the possibilities.) It's usual to put the redirections at the end, so you might surprise a future reader if you don't do that. However, it's only a matter of style. There is some benefit to putting input redirections before the command and output redirections afterward, particularly in pipelines, because it keeps the reading order identical to the processing order:
<input.txt command1 | command2 | command3 >output.txt
(contrast command1 <input.txt | command2 …
, which puts the origin after the first processing step.)
In compound commands, you do need to put the redirections at the end; for example, in the following snippets, you can't put the redirection anywhere else:
while some_predicate; do some_action; done <in >out
{ command1; command2; } <in >out
When there are multiple redirections, the order is important if they overlap, i.e. if they have file descriptors in common. See Order of redirections
In a pipeline, redirections apply to each piped command. In your examples, the redirections apply to (1) the sort
command only, (2,3) the echo
command only. As explained above, (2) and (3) are equivalent.
In (2) and (3), the output from echo
ends up at the same place it was before the redirection. If you'd written echo -en "C\nB\nA\n" >&2 | sort
, there would be no output to stdout from the command on the left-hand side of the pipe, so sort
would see an empty stdin.
You can redirect the input or output of a block of commands by putting them in braces:
{ command1 | command2; } 2>error.log
I assume your choice of redirections was for demonstration purposes only — 2>/dev/stdout >&2
is a complex way of writing 2>&1
(redirect standard error (i.e. fd 2) to wherever standard output (i.e. fd 1) currently goes).
2>/dev/stdout >&2
is zero. The question is primarily concerned with "where to place" and only secondarily with "what does" the redirection. – Tim Friske Nov 19 '12 at 09:182>/dev/stdout >&2
is most definitely not zero. – Chris Down Nov 19 '12 at 11:46>
is still/dev/stdout
after2>/dev/stdout >&2
. The redirection itself definetly has its side effects. – Tim Friske Nov 19 '12 at 13:48>&2
. Please read the man page first, then ask a clear question. – Mikel Nov 19 '12 at 15:14>&2
and the2>foo
but not with the placement of the redirection within a simple command or a pipeline. – Gilles 'SO- stop being evil' Nov 19 '12 at 23:092>/dev/stdout >&2
contains redundancies. The question needs to have these redundancies removed, and then be recast in the form of a clear question. If it was only about redirections in pipelines, it would indeed be useful. – Mikel Nov 19 '12 at 23:42