使用带有管道和符号的 grep 来过滤 find 中的错误

Hen*_*k K 29 command-line bash grep find

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

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

find -name 'myfile.*' |& grep -v "Permission denied"
Run Code Online (Sandbox Code Playgroud)

我不明白为什么需要将 & 符号放入此命令中,本以为它会起作用,但事实并非如此。

find -name 'myfile.*' | grep -v "Permission denied"
Run Code Online (Sandbox Code Playgroud)

请解释符号的含义。

bel*_*qua 34

在类 Unix 系统中,有两个输出路径,如果不加修改,会将输出发送到您的屏幕。标准错误(或 stderr)是捕获大多数失败和错误条件的错误。

要将 stderr 中的权限拒绝消息传递到与“常规输出”相同的输出流,您必须将两者结合起来。在您的示例中,为了grep -v正确操作它,您将 stdout(标准输出)和 stderr 与您看到的神秘语法结合起来。

来自GNU Bash 手册部分3.2.2 Pipelines

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

另外,正如 geirha 指出的那样,如果你只想摆脱 stderr 输出,你会想要做类似的事情

find -name 'myfile.*' 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

也许

find -name 'myfile.*' 2> /tmp/errorlog
Run Code Online (Sandbox Code Playgroud)

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

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

如果你省略了括号,而是这样做了——

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

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

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

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


Flo*_*sch 11

错误消息被写入stderr,而不是stdout,而只是|管道stdout

您可能想要|&,哪个管道stderr以及stdout