为什么 grep 在这里不使用管道工作?

mod*_*tos 25 shell grep pipe

我有以下命令:

find / -name libGL.so.1
Run Code Online (Sandbox Code Playgroud)

它返回很多带有“权限被拒绝”的行。我想排除这样的行,所以我添加了以下内容:

find / -name libGL.so.1 | grep -v 'denied'
Run Code Online (Sandbox Code Playgroud)

但输出是相同的 - 我grep -v 'denied'没有过滤掉带有Permission denied. 我尝试了很多变体,查看了 grep 教程,但我无法弄清楚问题所在。有什么建议?

ste*_*ver 54

这无关grep- 这是因为管道|重定向标准输出流,stdoutPermission denied消息在标准错误流中stderr。你可以达到你想要使用结合流的结果2>&1(重定向其文件描述符是流2给其文件描述符是流1),以便stderr以及stdout被输送到grep命令的输入

find / -name libGL.so.1 2>&1 | grep -v 'denied'
Run Code Online (Sandbox Code Playgroud)

但是stderr通过将其重定向到简单地完全丢弃它会更常见/dev/null

find / -name libGL.so.1 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

使用 |& 代替 2>&1 |

如果您查看 Bash 手册页,您可能会注意到以下内容:

如果|&使用,command的标准错误通过管道连接到command2的标准输入;它是 的简写2>&1 |

因此,如果您想加入 STDERR 和 STDOUT,也可以使用此构造:

find / -name libGL.so.1 |& grep -v 'denied'
Run Code Online (Sandbox Code Playgroud)

  • 关于组合它们的附加说明:如果由于某种奇怪的原因文件存在于 `/foo/bar/denied/libGL.so.1`,组合 `stdout` 和 `stderr` _then_ 过滤将隐藏结果 (3认同)

小智 5

你的命令应该是:

find / -name libGL.so.1 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

Find 抱怨标准错误 (fd2) 的权限。为了消除这些行,将 (>) 标准重定向到位桶 (/dev/null)。