I've written a script that has a few log outs with printf "..." 1>&2 inside a function. Running that script (build.sh) and I've noticed that if I want to redirect stderr to stdout and stdout to a file[0], success is dependent on order:

  • ./build.sh 2> /tmp/log.txt works (obviously)
  • ./build.sh 1>/tmp/log.txt 2>&1 works
  • ./build.sh 2>&1 1>/tmp/log.txt doesn't redirect to the file

And with echo:

  • echo "test" 2>&1 >/tmp/log.txt works
  • echo "test" >/tmp/log.txt 2>&1 works

This was replicated in bash, zsh, and originally reported in mksh.

When does the order of redirection statements in the command matter? Thanks!

0: Not sure why I'd do this, but a user of the script tried it and got confused when the redirection failed.


Order is important because the redirections are executed in the order they are listed from left to right. In your second example (correct) ./build.sh 1>/tmp/log.txt 2>&1 it first maps fd "1" to a file and then duplicates "1" as "2" and with this mapping executes the build script. In the 3rd example (not working) it first duplicates the current "1" as "2" and only after that maps "1" to a file. The current "1" was not the file at the time of duplication. It was your terminal or the CI shell script output grabber.

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