shell 管道标准误差和标准输出分别

p4rjhz4m  于 2023-01-13  发布在  Shell
关注(0)|答案(4)|浏览(153)

我想对特定命令的stdout和stderr执行不同的操作。

cmd |1 stdout_1 | stdout_2 |2 stderr_1 | stderr_2

其中stdout_x是专门用于stdout的命令,stderr_x是专门用于stderr的命令。如果 every 命令中的stderr通过管道传输到我的stderr命令中,这是可以的,但如果stderr可以严格地来自cmd,那就更好了。我一直在搜索一些可能支持这种做法的语法,但似乎找不到任何东西。

ymzxtsji

ymzxtsji1#

您可以使用不同的文件描述符

{ cmd 2>&3 | stdout_1; } 3>&1 1>&2 | stderr_1
    • 示例:**
{ { echo 'out'; echo >&2 'error'; } 2>&3 | awk '{print "stdout: " $0}'; } 3>&1 1>&2 |
  awk '{print "stderr: " $0}'
stderr: error
stdout: out

否则使用进程替换

cmd 2> >(stderr_1) > >(stdout_1)
    • 示例:**
{ echo 'out'; echo >&2 'error'; } 2> >(awk '{print "stderr: " $0}') \
> >(awk '{print "stdout: " $0}')
stderr: error
stdout: out

将stdout和stderr分别cmd中通过管道传输。

ryhaxcpt

ryhaxcpt2#

您可以使用进程替换和重定向来实现此目的:

cmd 2> >(stderr_1 | stderr_2) | stdout_1 | stdout_2
cdmah0mi

cdmah0mi3#

最直接的解决方案是这样的:

(cmd | gets_stdout) 2>&1 | gets_stderr

主要的缺点是如果gets_stdout本身在stdout上有任何输出,那么它也会输出到gets_stderr,如果这是一个问题,你应该使用anubhava或Kevin的答案。

nimxete2

nimxete24#

late-answer-和之前所有的答案一样,stderr在最后到达stdout(@anubhava的答案 * 几乎 * 完成)。
要独立地(或相同地)传输stderr和stdout并将它们保存在stdout和stderr中,我们可以使用文件描述符。

    • 溶液**:
{ { cmd | stdout_pipe ; } 2>&1 1>&3 | stderr_pipe; } 1>&2 3>&1
    • 说明**:
  • shell中的管道始终发生在stdout上(文件描述符1)
  • 因此,我们直接为stdout应用管道(stderr保持不变)
  • 然后,我们将stdout存放在临时文件描述符中,并将stderr移动到stdout,以便在下一步中通过管道传输
  • 最后,我们将"当前" stdout(管道化的stderr)返回到stderr,并将stdout从临时文件描述符返回
    • 示例**:

使用
指令= { echo 'out'; echo >&2 'error'; }
标准输出管道= awk '{print "stdout: " $0}'
标准错误_管道= awk '{print "stderr: " $0}'

{ { { echo 'out'; echo >&2 'error'; } \
  | awk '{print "stdout: " $0}'; } 2>&1 1>&3 \
  | awk '{print "stderr: " $0}'; } 1>&2 3>&1
    • 注意**:此示例有一对额外的{ },用于将两个echo命令"组合"为一个命令

当使用此函数重定向脚本的输出时,或者将此函数与着色stderr的终端一起使用时,您会看到不同之处。

相关问题