这个问题类似于 仅通过过滤器传输 STDERR ,但我想要 STDOUT 和 STDERR 并且不希望合并输出。
我想要:
STDOUT ── [ filter ] ────> STDOUT
STDERR ── [ filter ] ────> STDERR
在 Bash 中我可以做:
myprogram() {
echo stdout;
echo stderr >&2;
}
myfilter() {
echo "$@"
cat
}
{ myprogram; } 2> >(myfilter errfilter >&2) | myfilter outfilter
wait
echo Done
我想在 /bin/sh 中做同样的事情。但没有
>(cmd)
构造。
在 /bin/sh 中我可以做:
{ myprogram; } 2>/tmp/tmpfile | myfilter outfilter
myfilter errfilter </tmp/tmpfile >&2
echo Done
(如果来自
myprogram
的 stderr 大于磁盘,这将会失败)。
或者:
mkfifo /tmp/tmpfifo
myfilter errfilter </tmp/tmpfifo >&2 &
{ myprogram; } 2>/tmp/tmpfifo | myfilter outfilter
wait
echo Done
(如果
/tmp
是只读的,这将会失败)。
可以在/bin/sh中完成而不使用临时文件或命名管道吗?
我在想这是否可以通过一些
exec 2>&- 3>&1
魔法来完成。
这不起作用,但我感觉只要有正确的
exec
魔法,它就可以起作用:
exec 3>&2
myfilter errfilter <&3 >&2 &
{ myprogram; } 2>&3 | myfilter outfilter
wait
echo Done
未详细测试,但似乎有效:
exec 3>&1 4>&2
# Run mycmd and redirect stdout to myprog1 and stderr to myprog2
{
{ myprogram 2>&1 1>&3 3>&- 4>&1 | myfilter err 3>&- 4>&-; } 2>&1 1>&4 | myfilter out
} 3>&1 4>&2
# Close file descriptors
exec 3>&- 4>&-