I have this bash function:

 "$@"  \
      2> >( while read line; do echo -e "r2g: $line"; done ) \
      1> >( while read line; do echo -e "r2g: $line"; done )

this function is only supposed to be sourced and run by bash, but for some godforsaken reason, it's being sourced/run by sh.

You use the above function like so:

zmx foo bar

and it will prepend r2g: to the stdout/stderr from the foo command.

So my question is — does anyone know how to translate the above bash function into something sh can work with?

Right now I get a syntax error when sh interprets that function. I have been struggling for months to figure out why sh is invoked to interpret the function, but I pretty much gave up trying to prevent sh from doing so.

  • Why are you using echo -e? Do you specifically want to expand escaped characters? Jul 13, 2018 at 9:49

2 Answers 2


Here’s another approach which works with POSIX sh:

zmx() {
    "$@" 2>&1 | sed 's/^/r2g: /'

This avoids having to deal with read’s subtleties.

To check such shell snippets yourself, you can use ShellCheck: add a #!/bin/sh shebang to tell it you want to use a POSIX shell, and it will tell you what to fix.


The following should work in sh:

"$@" 2>&1 | while read line ; do echo -e "r2g: $line" ; done

Note that the behaviour of echo -e might be different in sh (e.g. it might actually output -e r2g: ....)

  • Yes, POSIX sh ignores -e. This also mangles backslashes (thanks to read). Jul 13, 2018 at 7:52
  • 1
    And leading whitespace. @StephenKitt Jul 13, 2018 at 8:06
  • Why not just use printf then?
    – Kusalananda
    Jul 13, 2018 at 9:08
  • I'm not sure why the -e was there from the beginning. printf needs to be tested, the variable might contain some % that you don't want to be interpreted, but some \t or whatever that you want to interpret.
    – choroba
    Jul 13, 2018 at 9:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .