Redirected output hangs when using tee Redirected output hangs when using tee unix unix

Redirected output hangs when using tee


It seems like, for some reason, using tee stops the prompt ($PS1) from appearing because the shell script has not exited. As a workaround, I generally use a short sleep after calling tee.

#!/bin/bashexec > >(tee -a mylog)sleep .1# my code


Converting comments into an answer, with minor edits.

I noted:

The following code exits OK for me on Mac OS X 10.10.3.

OPT_LOG=file.nameif [[ $OPT_LOG ]]then exec > >(tee -a $OPT_LOG)fifor ((i = 0; i < 10; i++))do    echo "Logging message $i at $(date)"    sleep 1done

Your problem is probably in the code you've not shown. What commands are you running? What do you get from bash -x yourscript.sh?

And chatraed observed

If you remove the sleep and date calls from your example, the script does not exit properly any more, as told by Andrew:

OPT_LOG=file.name;if [[ $OPT_LOG ]]; then exec > >(tee -a $OPT_LOG); fi;for ((i = 0; i < 10; i++)); do echo "Logging message $i"; done

And I responded:

Now that's an interesting observation! I can reproduce your result.

I experimented a bit:

  • I added a pwd before the for loop with 'just the echo', and that didn't affect things (but pwd is probably a Bash built-in).
  • I added bash -c 'exit 0' (which is not a built-in) and the code terminated OK.
  • I tried using > >(tee -a $OPT_LOG &) and the output didn't appear — on screen or in the file. (I find this surprising, but it was an attempted workaround, not a major part of the work.)

My impression is that Andrew has found a bug in Bash that could viably be reported. (See the Bash manual on Reporting Bugs for how to do that.) I don't think that not exiting simply because no external commands have been executed since the I/O redirection is OK. I can confirm that Apple's Bash 3.2.57 has the problem; so does Bash 4.3.27 (which I built for myself so it is patched with the fixes to the ShellShock bug).

It is relatively unusual that a shell script does not invoke any external command, and invoking any external command after the exec redirection seems to suppress the bug.

It also confirms that chatraed's workaround works, albeit more slowly than minimally necessary. For production use, I'd choose sleep 0, which is most of a tenth of a second faster than sleep 0.1. And sleeping for a fraction of a second only works on some systems; classically (and according to POSIX), sleep does not sleep for fractional seconds. OTOH, if you write sleep 0.1, on systems without support for fractional seconds, including the leading 0 probably makes it sleep for zero seconds anyway; writing .1 might or might not have the same effect.