-   Linux - Server (
-   -   Don't Understand Duplicate File Descriptors in Bash (

dcparris 12-28-2011 10:44 AM

Don't Understand Duplicate File Descriptors in Bash
Hi all,

I am confused about duplicating file descriptors in Bash. Reading through Mark Sobell's "Practical Guide to Linux...", I ran across this example:

$ cat x y 1> hold 2>&1
$ cat hold

cat: x: No such file or directory
This is y.
Both the error and the contents of 'y' go to the file 'hold'. It appears to be effectively equivalent to this:

$ cat x y &> hold
$ cat hold

(same output as above)

But I am not sure what the point is. The first example seems like going the long way around the barn to me (and confusing to read). It's ok to take the long way, as long as there is a purpose to it. I'm sure there is a purpose, but I just don't quite get it. Is there any particular advantage to using the first method over the second one? Or maybe one works better than the other in certain scenarios?

Sobell labels the first one as a duplicate descriptor, and the second is an example of combining stdout and stderr. Combining, duplicating... making my head hurt.

rknichols 12-28-2011 01:22 PM

Those are illustrations of two similar actions, and for this simple case the result is exactly the same. As is common for trivial examples, there's no advantage for doing it the "long" way (though the "&>" syntax is, I believe, a somewhat newer addition to the shell, so you'll find a lot of older scripts using the "duplicate" syntax). Think of the combining operation ("&>") as a shorthand notation for a common, simple case that does not extend to more complex situations or file descriptors other than stdout and stderr.

David the H. 12-28-2011 07:50 PM

The key difference is very simply that the first pattern is fully portable, while the second one is a bash-specific shortcut for it. If you aren't using bash, you can't do the latter (unless some other shell has also adopted it that I don't know about).

File descriptors are certainly a hard thing to get your head around, and I'm still not all that proficient myself. But there are two confusing points, both related, that I finally understood that helped to clarify how it works.

1) The program sends its two kinds of output to file descriptors 1 and 2, and all the redirections you do for fd1 and fd2 are for these these two original outputs.

So this:

command 1>&2 2>file
...means that the command's stdout is redirected to the shell's stderr output, and the command's stderr is redirected to the file. It does NOT mean that you're sending fd1 into fd2, and then fd2 into the file, as if they were chained together. The second point is also involved here...

2) "&2" does NOT mean "stderr". It means "to the place fd2 is currently pointing". & references the target of the file descriptor, not the descriptor itself.

So taking these two:


command 2>&1 1>file
command 1>file 2>&1

The first one means, "send the command's stderr to the current target of fd1, which is the screen, and the command's stdout to the file".

The second line says "send the command's stdout to the file, and send the command's stderr to the current target of fd1, which has just been redefined as the file". Therefore both outputs go into the file.

I hope that helps clear it up a bit. :)

dcparris 12-29-2011 12:27 AM

Thanks guys! I think I understand a little better now. I won't swear to it, but I believe so. @David the H: I did play with this in all three forms you presented here, using one file and one erroneous filename. Just reading made my head hurt more than before, but after tinkering a bit, I feel better about it now.


All times are GMT -5. The time now is 08:15 AM.