现在我有这个:
echo "$run_test" | bash 2>&1 | prepend "r2g-test:" "yellow";
其作用是在 stdout/stderr 的每一行前面添加“r2g-test:”。因为我将 stderr 发送到 stdout,所以prepend
程序不知道其中的区别,因为它都是标准输入。
有什么方法可以将 stderr 发送到不同的prepend
实例吗tee
?
也许是这样的?
echo "$run_test" | bash 2> $(prepend 'r2g-test:' 'red') | prepend 'r2g-test:' 'yellow';
通过进程替换,这可能会起作用:
bash 2> >(prepend 'r2g-test:' 'red')
但到目前为止,stderr 从未出现在终端中
答案1
首先,让我们创建一个run_test
生成 stdout 和 stderr 的程序:
$ run_test() { while sleep 0.2; do echo "Out $((++c))"; echo "err$c">&2; done; }
现在,让我们将 stdout 和 stderr 发送到不同的过滤器。由于我没有prepend
安装,我将用于sed
相同的目的:
$ exec 3>&2; { run_test | sed 's/^/stdout: /'; } 2>&1 1>&3 | sed 's/^/stderr: /'
stdout: Out 1
stderr: err1
stdout: Out 2
stderr: err2
stdout: Out 3
stderr: err3
怎么运行的
exec 3>&2
这将创建文件描述符 3 作为 stderr 的副本。
run_test | sed 's/^/stdout: /'
这将运行
run_test
并添加stdout:
到标准输出的开头。{ run_test | sed 's/^/stdout: /'; } 2>&1 1>&3
2>&
将 stderr 重定向到 stdout,以便 stderr 将进入下一个管道。1>&3
将 stdout 重定向到 stderr,以便它显示在终端上。{ run_test | sed 's/^/stdout: /'; } 2>&1 1>&3 | sed 's/^/stderr: /'
最后一个管道捕获 run_test 的 stderr(现在是 stdout)并添加
stderr:
到它的前面。
使用进程替换
$ run_test > >(sed 's/^/stdout: /') 2> >(stdbuf -oL sed 's/^/stderr: /' >&2)
stdout: Out 1
stderr: err1
stdout: Out 2
stderr: err2
stdout: Out 3
stderr: err3
以上使用的stdbuf
是 Linux 上的标准。对于其他操作系统,需要寻找类似的命令。