A Bourne shell gotcha: redirection order

August 10, 2006

I was reminded of this by seeing it in a shell script recently: the order that you do redirection in on a command line can be important. This means that the following two lines are not equivalent:

foobar 2>&1 >/some/where
foobar >/some/where 2>&1

The first one sends standard error to wherever the current standard output is, and then sends standard output to /some/where; the latter sends both standard output and standard error to /some/where.

This (only) happens when you are redirecting to file descriptors, because the redirections are applied left to right and use the current 'value' of that file descriptor, even if the file descriptor will later be sent somewhere else by a later redirection.

This is unfortunately an easy mistake to make and a pernicious one to boot, since you may not notice it for a while (for example, if foobar produces errors only rarely).

Sidebar: more redirection idioms

While I'm writing this stuff down, there's some common Bourne shell redirection idioms that are worth remembering:

echo error message 1>&2
This redirects error messages from shell scripts to standard error, where they should go.
exec >/some/where 2>&1
This redirects all further output from the script and things it runs to /some/where. (You can obviously use it to redirect just stdout or stderr alone, as desired.)

You can play rather obscure tricks by using high file descriptors in creative ways. For example, the following ugly incantation swaps standard output and standard error:

foobar 5>&2 2>&1 1>&5 5>&-

This has the defect that it destroys file descriptor 5, which hopefully wasn't already being used for anything important.

Written on 10 August 2006.
« A Bourne shell irritation
An unhappy spam milestone »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu Aug 10 15:25:48 2006
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.