piping stderr and stdout separately

2019-06-25 16:57发布

I'd like to do different things to the stdout and stderr of a particular command. Something like

cmd |1 stdout_1 | stdout_2 |2 stderr_1 | stderr_2

where stdout_x is a command specifically for stdout and stderr_x is specifically for stderr. It's okay if stderr from every command gets piped into my stderr commands, but it's even better if the stderr could be strictly from cmd. I've been searching for some syntax that may support this, but I can't seem to find anything.

标签: bash shell
3条回答
欢心
2楼-- · 2019-06-25 17:21

The most straightforward solution would be something like this:

(cmd | gets_stdout) 2>&1 | gets_stderr

The main drawback being that if gets_stdout itself has any output on stdout, that will also go to gets_stderr. If that is a problem, you should use one of anubhava's or Kevin's answers.

查看更多
对你真心纯属浪费
3楼-- · 2019-06-25 17:22

You can make use of a different file descriptor:

{ cmd 2>&3 | stdout_1; } 3>&1 1>&2 | stderr_1

Example:

{ { echo 'out'; echo >&2 'error'; } 2>&3 | awk '{print "stdout: " $0}'; } 3>&1 1>&2 |
  awk '{print "stderr: " $0}'
stderr: error
stdout: out

Or else use process substitution:

cmd 2> >(stderr_1) > >(stdout_1)

Example:

{ echo 'out'; echo >&2 'error'; } 2> >(awk '{print "stderr: " $0}') \
> >(awk '{print "stdout: " $0}')
stderr: error
stdout: out

to pipe stdout and stderr separately from your cmd.

查看更多
再贱就再见
4楼-- · 2019-06-25 17:29

You can use process substitution and redirection to achieve this:

cmd 2> >(stderr_1 | stderr_2) | stdout_1 | stdout_2
查看更多
登录 后发表回答