Prefix all lines on standard error Is this the best way to prefix all lines written by a Bash script to standard error?

#! /bin/bash

exec 3&gt;&amp;2
exec 2&gt; &gt;(sed 's/^/ERROR: /' &gt;&amp;3)

echo stdout
echo stderr &gt;&amp;2


I am wondering, if I have to close file descriptor 3.
There's not a lot to review here.  It's Valgrind clean, though that's not difficult to achieve.

Certainly consider closing stream 3, unless you want to keep a means to emit unprefixed stderr messages.

One shortcoming is that the shell won't wait for sed to finish when it terminates.  If the last process's output is still being filtered at this point, then you may fail to capture it - I observed this (repeatably) when running the program in Emacs compilation-mode.

One way you can improve on this if you're using GNU sed is by passing -u ("unbuffered") flag to sed.  If you don't have GNU sed but do have GNU coreutils, then the stdbuf utility could make sed line-buffered for you:

stdbuf -oL -iL sed 's/^/ERROR: /'


With any sed, we could (and should) close stderr when we terminate and wait for sed to finish to be sure of catching all error output.



Modified code

#!/bin/bash

exec 3&gt;&amp;2
exec 2&gt; &gt;(sed -u 's/^/ERROR: /' &gt;&amp;3)
exec 3&gt;&amp;-
# shellcheck disable=SC2064
trap "exec 2&gt;&amp;-; wait $!" EXIT

echo stdout
echo stderr &gt;&amp;2