过滤stderr和stdout,但以/bin/sh兼容的方式将它们保留在stderr和stdout上

问题描述 投票:0回答:1

这个问题类似于 仅通过过滤器传输 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
sh exec file-descriptor
1个回答
0
投票

未详细测试,但似乎有效:

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>&-
© www.soinside.com 2019 - 2024. All rights reserved.