Take the 2-minute tour ×

I saw a bash script which had exec 1>&2 command in a function. Something like:

function example()
    exec 1>&2
    cat <<EOT
Script requires at least one parameter.
    exit 1

As I understand, exec 1>&2 means that everything from this point one will be directed to stderr. Is this some sort of fixed behaviour of exec one needs to know by heart or is there some good explanation behind this? I mean as I understand, exec in Bash script just invokes a command taking the same PID which the Bash script had and once the command is finished, the PID is killed. 1>&2 isn't a command. Could somebody explain the details(especially the why question) behind the exec 1>&2 command?

share|improve this question
In this case, the code is a verbose way of writing: echo "Script requires at least one parameter" 1>&2. Further, the error message is not helpful; you have to guess what that parameter is. A better message would be: echo "Usage: $(basename $0 .sh) filename [...]" 1>&2" to tell you (remind you) about the correct usage and what is to be provided. And using 4 lines to do the work of one is a bit OTT. It there were many lines to 'echo', then the redirection makes more sense, but could still be done with cat 1>&2 <<EOT followed by the 'here document'. –  Jonathan Leffler Jan 17 '12 at 0:47
@JonathanLeffler: I agree. And it's kind of evil to put exec 1>&2 at the beginning of a brace-wrapped function that does other things, because that side effect persists after the function returns. (Admittedly, this function calls exit 1, but this idiom shouldn't even exist.) –  ruakh Jan 17 '12 at 0:54
@ruakh: Doing it inside a function is not, in general, very nice - but could be correct if that's the intended behaviour of the function. The idiom itself is useful, used properly. This is a very borderline instance of 'used properly' (as in, I think it is somewhere on the wrong side of the border, over into the 'improper use' territory). –  Jonathan Leffler Jan 17 '12 at 1:32
@JonathanLeffler: Yeah, I think we're agreeing. If the intended behavior of the function is to redirect standard-output, that's one thing; but if it does other things, then it shouldn't just-incidentally redirect standard-output as well. –  ruakh Jan 17 '12 at 1:50
add comment

3 Answers

up vote 9 down vote accepted

exec is a built-in Bash function, so it can have special behavior that an external program couldn't have. In particular, it has the special behavior that:

If COMMAND is not specified, any redirections take effect in the current shell.

(That's quoting from the message given by help exec.)

This applies to any sort of redirection; you can also write, for example, any of these:

exec >tmp.txt
exec >>stdout.log 2>>stderr.log
exec 2>&1

(It does not, however, apply to pipes.)

share|improve this answer
add comment

The why is an accident of history, there isn't a great reason for it.

The redirection operators are applied to any program (for example, cat) and the >& form was added to express the "duplicate file descriptor 1 from 2" because it was useful. The >& syntax probably was used because they were running out of special characters and >& was nonsense given the basic meaning of & and > (but don't quote me on that). This stuff all dates back to the early Bourne shell around 1977.

Why exec plus a redirection to alter the input and output of the current shell? Probably because there was already a meaning for the null command > path which had the same effect as cat /dev/null > path but was easier to type, and when your teletype ran at 10 characters per second at best, that mattered. So the exec built-in was then overloaded: with no arguments, it applied the redirection operations to itself.

Since bash tries to adhere to Bourne shell convention as much as possible, you get these antiquities which, as you suspect, you just have to remember especially if you are trying to impress other members of the appropriate sex (i.e. "chicks dig a guy who knows his i/o redirection arcana").

share|improve this answer
"Chicks dig ..."? Ye Optimist! –  Jonathan Leffler Jan 17 '12 at 1:33
+1 for your final sentence. Obviously, there's very little more alluring than depth of bash lore. –  tandrewnichols Oct 25 '13 at 18:30
add comment

Original source: http://tldp.org/LDP/abs/html/x17784.html

An exec <filename command redirects stdin to a file. From that point on, all stdin comes from that file, rather than its normal source (usually keyboard input). This provides a method of reading a file line by line and possibly parsing each line of input using sed and/or awk.

Similarly, an exec >filename command redirects stdout to a designated file. This sends all command output that would normally go to stdout to that file.

Note that exec N > filename affects the entire script or current shell. Redirection in the PID of the script or shell from that point on has changed. However, N > filename affects only the newly-forked process, not the entire script or shell.

Further reading that will interest you can be found @ http://tldp.org/LDP/abs/html/io-redirection.html. There are lots of neat little redirection tricks you can do.

share|improve this answer
add comment

Your Answer


