将grep与管道和&符号一起使用以过滤来自find的错误


22

我正在使用cygwin在cygdrive上查找文件。

但是,我需要抑制权限被拒绝的消息(否则结果将隐藏在错误消息中)。以下命令有效:

find -name 'myfile.*' |& grep -v "Permission denied"

我不明白为什么要在此命令中添加“&”号,并期望它能够正常工作,但事实并非如此。

find -name 'myfile.*' | grep -v "Permission denied"

请解释“&”号的含义。

Answers:


24

在类似Unix的系统中,有两个输出路径,如果不修改它们,会将输出发送到屏幕。标准错误(或标准错误)是捕获大多数故障和错误情况的标准错误。

要将stderr中的拒绝权限消息传递到与“常规输出”相同的输出流,必须将两者结合。在您的示例中,为了使您grep -v能够对其进行正确的操作,您将stdout(标准输出)和stderr与所看到的奥术语法结合使用。

GNU Bash手册3.2.2管道

如果使用' |&',则command1的标准错误,除了其标准输出外,还将通过管道连接到command2的标准输入;它是的简写2>&1 |。将标准错误隐式重定向到标准输出是在命令指定的任何重定向之后执行的。

此外,正如geirha所指出的那样,如果您想摆脱stderr输出,您可能想做些类似的事情

find -name 'myfile.*' 2> /dev/null

也许

find -name 'myfile.*' 2> /tmp/errorlog

并注意,如果您有命令字符串,例如find将其输出传递给xargs您,则需要将整个命令管道放在括号中,以捕获命令所有组件的输出。例如,

(find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 )  2> /dev/null

如果您省略了括号,而是这样做了-

find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 2> /dev/null

您仍然会从find或egrep中看到权限被拒绝的错误,但是stderr将被重定向到xargs。

如您所见,只有在测试运行期间查看stderr的内容之后,您才有可能丢弃stderr。

请注意,对于GNU find,据我所知,任何POSIX兼容的find,该-print选项都是隐式的。如果愿意,您仍然可以明确提供它。



1
@LukeExton是的。在其他Shell中,2>&1 |可以代替使用|&(即,可以将stderr显式重定向到stdout,然后将其通过管道传递到管道中的下一个命令)。
伊莱亚·卡根

2> >( grep filter )也很方便
user1133275


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.