I am porting an old ksh script to Bourne shell. The old ksh script contains the following code:



exec 1> $tmpLog
exec 2>&1

eval $*

From what I read, it seems that these two exec statements are intended to execute $*, another_command_1, another_command_2 and all following commands; and then redirect all STDERR and STDOUT from those commands into /var/tmp/logfile.$$. However, when I run this in a script the script fails after exec 2>&1.

stefanl@host:~ $ sh -xv ./output.sh echo "Hello"

+ tmpLog=/var/tmp/logfile.39918

exec 1> $tmpLog
+ exec
exec 2>&1
+ exec
stefanl@host:~ $

And when I run this on the commandline, my shell freezes after I execute exec 2>&1:

stefanl@host:~ $ tmpLog=/var/tmp/logfile.$$
stefanl@host:~ $ exec 1> $tmpLog
stefanl@host:~ $ exec 2>&1
### FREEZE ###

My questions:

  1. What is exec 2>&1 supposed to do?
  2. Why is it failing for me?

2 Answers 2


Your script is not failing - it's working just fine. Your understanding is correct in that exec >logfile; exec 2>&1 redirects both standard output and standard error to logfile. So, you should be looking in the log file and not your terminal for output and error. If you perform those redirections directly in your current shell, it looks like your shell has frozen because you sent all the output away from your terminal.

Note that the output from the xtrace (set -x) option also goes to standard error, which is always file descriptor 2 ... which you sent away to the log file. You should find the rest of it after the exec 2>&1 in there.

  • Ah, thanks! And if I open a new window and do a tail -f /var/tmp/logfile.39918 I see everything that I type in the old window. Clever trick! Commented Jul 31, 2012 at 19:35
  • 1
    "... sends both standard output and standard input to logfile, ..." should be "standard output and standard error". I'll edit to make the correction. Commented Feb 9, 2014 at 14:48

This form of exec (i.e. without a command) is used to redirect all subsequent output from the current shell interpreter.

from bash's built-in help:

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.

I use exec &> logfile to redirect stdout and stderr at the same time. e.g. most of my backup and rsync wrapper scripts (or any script that produces lots of output that I might want to examine in detail later) start with something like this:

BNAME=$(basename "$0" .sh)
savelog "$LOGFILE"
exec &> "$LOGFILE"

I then run the script from cron, or in the background and use tail -F to watch the logfile as the script is running. The savelog lets me keep the output from the last 7 runs (7 by default, savelog -c can be used to change that).

  • The question specifically targets the Bourne shell. Bourne doesn't have the &> operator, nor is quoting the bash man page terribly helpful. The part about cron is irrelevant.
    – jw013
    Commented Jul 31, 2012 at 23:23
  • It still clearly answered his first question 'What is exec 2>&1 supposed to do?` which hadn't actually been answered yet. Assuming a reasonable ability to understand, generalise and extrapolate doesn't deserve a -1. I tend to prefer providing a general explanation instead of just cargo-cult magic to a specific question. BTW, it was the bash help, not the bash man page...it just happened to be the most convenient and succinct documentation to hand, and the relevant point about taking effect in the current shell applies to all versions of sh.
    – cas
    Commented Jul 31, 2012 at 23:33
  • I don't see any part in your answer that specifically explains what exec 2>&1 does? I generally downvote answers that encourage misconceptions, whether explicitly or implicitly (in your case, implying sh = bash), because not every person who reads your answer in the future will know the difference. bash is based on sh but in practice there are many differences (like the &>: putting that in a Bourne shell script will probably break it). Also, none of those options that bash exec accepts are likely to be valid.
    – jw013
    Commented Aug 1, 2012 at 14:28
  • My first sentence explains it. As does the final sentence in the bash help output. The remainder is an example of why and how such a feature could be used - why and how typically being omitted from man pages and other reference material.
    – cas
    Commented Aug 1, 2012 at 22:24
  • 1
    Q. "What is exec 2>&1 supposed to do?". A. "This form of exec (i.e. without a command) is used to [...]". There is no confusion between bash and sh in that sentence. It is true for all variants of sh. You ignored his first question and answered his second, I ignored his second and answered his first. You're judging my answer by the question you answered, not by the one I answered.
    – cas
    Commented Aug 1, 2012 at 23:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .