2

I have a bash script executing a long run command. I want to prefix each line printed by the command to stdout with $stdprefix and each line printed to stderr with $errprefix.

I don't want to store output to variables or even worse to files, because I'd have to wait until the command finishes execution to see the output.

kopiczko
  • 3,018
  • 1
  • 17
  • 24

1 Answers1

1

You can use:

# your prefixes
stdprefix="stdout: "
errprefix="stderr: "

# sample command to produce output and error
cmd() { echo 'output'; echo >&2 'error'; }

Now to redirect stdout and stderr independently:

{ cmd 2>&3 | awk -v p="$stdprefix" '{print p $0}'; } 3>&1 1>&2 |
  awk -v p="$errprefix" '{print p $0}'
stderr: error
stdout: output

Just replace cmd with your long running command.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Thank you. I would also redirect output of second awk to stderr. It would look like this: { cmd 2>&3 | awk -v p="$stdprefix" '{print p $0}'; } 3>&1 1>&2 | awk -v p="$errprefix" '{print p $0}' >&2 – kopiczko Jan 10 '15 at 13:09
  • That redirect I proposed in my previous comment prints **everything** to stderr. Anyway during studying your answer I found this http://stackoverflow.com/a/3618208/3087441 which works like a charm. So my final code is `cmd 2> >( sed 's/^/$errprefix/' >&2 ) | sed 's/^/$stdprefix/'` – kopiczko Jan 10 '15 at 14:53
  • Yes you can use process substitution also but make sure you redirect stderr before stdout using that. Basically `cmd 2> >(stderr_handler) | stdout_handler` form. – anubhava Jan 10 '15 at 14:57