Copy *unbuffered* stdout to file from within bash script itself

I want to copy stdout to a log file from within a bash script, meaning I don’t want to call the script with output piped to tee, I want the script itself to handle it. I’ve successfully used this answer to accomplish this, using the following code:

#!/bin/bash
exec > >(sed "s/^/[] /" | tee -a myscript.log)
exec 2>&1

# <rest of script>
echo "hello"
sleep 10
echo "world"

This works, but has the downside of output being buffered until the script is completed, as is also discussed in the linked answer. In the above example, both “hello” and “world” will show up in the log only after the 10 seconds have passed.

I am aware of the stdbuf command, and if running the script with

stdbuf -oL ./myscript.sh 

then stdout is indeed continuously printed both to the file and the terminal.
However, I’d like this to be handled from within the script as well. Is there any way to combine these two solutions? I’d rather not resort to a wrapper script that simply calls the original script enclosed with “stdbuf -oL”.


Source: shell

Leave a Reply