2
\$\begingroup\$

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

#! /bin/bash

exec 3>&2
exec 2> >(sed 's/^/ERROR: /' >&3)

echo stdout
echo stderr >&2

I am wondering, if I have to close file descriptor 3.

\$\endgroup\$

1 Answer 1

8
\$\begingroup\$

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>&2
exec 2> >(sed -u 's/^/ERROR: /' >&3)
exec 3>&-
# shellcheck disable=SC2064
trap "exec 2>&-; wait $!" EXIT

echo stdout
echo stderr >&2
\$\endgroup\$
3
  • \$\begingroup\$ It is possible to wait for the process substitution. The pid of the child process is in $! after the exec. In order to flush the output of the child process, it is sufficient to close the input fd, which is fd 2 of the parent. After that one can wait for the child pid. \$\endgroup\$ Commented Jan 29, 2020 at 13:28
  • \$\begingroup\$ Good suggestion; thanks @ceving. I've made the appropriate change. \$\endgroup\$ Commented Jan 29, 2020 at 17:11
  • \$\begingroup\$ That was a typo - &1 where I meant &-. Sorry! \$\endgroup\$ Commented Jan 29, 2020 at 17:12

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.