Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

My question is about redirection precedence is bash. Suppose you have a command:

cmd1 < cmd2 > cmd3

Would it translate to:

(cmd1 < cmd2) > cmd3

Or

cmd1 < (cmd2 > cmd3)

share|improve this question
add comment

2 Answers 2

up vote 6 down vote accepted

The POSIX standard specifies that shell redirection is from left to right; that is, order is significant:

The construct 2>&1 is often used to redirect standard error to the same file as standard output. Since the redirections take place beginning to end, the order of redirections is significant. For example:

ls > foo 2>&1

directs both standard output and standard error to file foo. However:

ls 2>&1 > foo

only directs standard output to file foo because standard error was duplicated as standard output before standard output was directed to file foo.

bash operates in compliance with this part of the standard:

$ ls doesnotexist > foo 2>&1
$ cat foo
ls: cannot access doesnotexist: No such file or directory
$ ls doesnotexist 2>&1 > foo
ls: cannot access doesnotexist: No such file or directory
$ cat foo
$ 

As for piping:

Because pipeline assignment of standard input or standard output or both takes place before redirection, it can be modified by redirection. For example:

$ command1 2>&1 | command2

sends both the standard output and standard error of command1 to the standard input of command2.

share|improve this answer
    
That assumes that the Bash shell is POSIX-complient. –  fpmurphy1 Jun 2 '11 at 16:13
1  
I am not getting it. Since you said order is from left to right, shouldn't ls > foo 2>&1 mean redirect stdout to foo then redirect stderr to stdout. So this shouldn't work. Similarly second command should work. What am I missing here? –  Deepak Mittal Jun 2 '11 at 17:31
1  
@fpmurphy bash is generally POSIX compliant, except in the situations outlined here, where the default bash behavior differs. To make bash conform more, you can use the --posix option. –  Matt Eckert Jun 2 '11 at 18:08
    
@dpacmittal The first example, ls > foo 2>&1, operates like this: first, standard output is redirected to foo, then, standard error is redirected to standard output, which is now the file foo. The second example, ls 2>&1 > foo, operates like this: standard error is redirected to standard output before standard output is redirected to foo, so standard error is echoed locally instead of being directed to the file. –  Matt Eckert Jun 2 '11 at 18:15
3  
@dpacmittal.. re ls 2>&1 >foo maybe you can think of it like this. stderr from 'ls' is redirected to stdout. This will happen! It will go to where stdout is currently assigned to go, regardless of any further directives relating to stdout.. (because this is its prime/first directive).. Then along come another directive which says that stdout will go to "foo", and it does... Remember: stderr is not transmuted into actually becoming stdout.. It just goes to where stdout was assigned at the time of the directive. (eg, the terminal) –  Peter.O Jun 2 '11 at 18:45
show 4 more comments

I guess neither. A pair of parenthesis means a sub-shell. But in this case, no sub-shell will be started because of the redirection. Bash simply feeds cmd2 into stdin and feeds stdout into cmd3.

I'm thinking, do you mean something like cmd1 | cmd2 | cmd3? Because your cmd2 and cmd3 are usually normal files instead of "cmds".

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.