协慌网

登录 贡献 社区

如何管 stderr,而不是 stdout?

我有一个要写入信息的程序stdoutstderr ,我需要grep通过什么是未来标准错误 ,而忽视标准输出

我当然可以分 2 步完成:

command > /dev/null 2> temp.file
grep 'something' temp.file

但我宁愿能够在没有临时文件的情况下做到这一点。有没有任何智能管道技巧?

答案

首先将 stderr 重定向到 stdout - 管道; 然后将 stdout 重定向到/dev/null (不改变 stderr 的去向):

command 2>&1 >/dev/null | grep 'something'

有关各种 I / O 重定向的详细信息,请参阅 Bash 参考手册中有关重定向的章节。

请注意,I / O 重定向的顺序是从左到右解释的,但在解释 I / O 重定向之前会设置管道。文件描述符(如 1 和 2)是对打开文件描述的引用。操作2>&1使文件描述符 2 也称为 stderr 引用与文件描述符 1 相同的打开文件描述,也就是 stdout 当前引用的(参见dup2()open() )。操作>/dev/null然后更改文件描述符 1,以便它引用/dev/null的打开文件描述,但这不会改变文件描述符 2 引用打开文件描述的事实,文件描述符 1 是最初指向 - 即管道。

或者在使用时交换 stderr 和 stdout 的输出: -

command 3>&1 1>&2 2>&3

这将创建一个新的文件描述符(3)并将其分配到与 1(stdout)相同的位置,然后将 fd 1(stdout)分配给与 fd 2(stderr)相同的位置,最后将 fd 2(stderr)分配给相同的位置放置为 fd 3(标准输出)。 Stderr 现在可以作为 stdout 使用,旧 stdout 保存在 stderr 中。这可能有点过分,但希望提供有关 bash 文件描述符的更多详细信息(每个进程有 9 个可用)。

在 Bash 中,您还可以使用进程替换重定向到子 shell:

command > >(stdlog pipe)  2> >(stderr pipe)

对于手头的情况:

command 2> >(grep 'something') >/dev/null