'grep' 命令的退出状态码是什么?

12

在退出状态部分,grep手册报告:

退出状态
       如果找到了选择的行,则退出状态为0,如果未找到则为1。如果发生错误,则退出状态为2。(注意:POSIX错误处理代码应检查“2”或更大值。)

但是命令:

echo ".
..
test.zip"|grep -vE '^[.]'
echo $?

echo "test.zip
test.txt"|grep -vE '^[.]'
echo $?

返回的值总是0。我本来期望是1和0。我做错了什么?

4
如果grep没有找到匹配项,则退出状态为1。 你提供的两个示例都至少返回一行匹配项,因此两种情况的退出状态均为0 - Sundeep
你的问题可以被替换为:“为什么 grep -vE '^[.]' <<<$'.\na'; echo $? 输出0?” - Micha Wiedenmann
@Sundeep 没有匹配'^[.]'的内容,只匹配以点开头的内容,可能没有清楚表明输入是多行的。 - banda bassotti
@MichaWiedenmann 是的,但问题不在于此。 - banda bassotti
1
@bandabassotti,我可以友善地建议您一下吗?您可能有点困惑,sundeep 解释说正是因为该行是多行的,并且有一行与您的模式匹配,所以您才得到了结果。(Grep 是基于行的。) - Micha Wiedenmann
-v 选项选择不匹配模式的行。您发布的两个命令行都包含不匹配 ^[.] 模式的行。 - axiac
1个回答

4
记住,grep 是基于行的。如果任何一行匹配,你就会得到一个匹配结果。(在你的第一个例子中,test.zip 匹配(更准确地说:你使用了 -v,因此你要求返回不符合模式的行,而 test.zip 恰好不符合模式。因此,你的 grep 调用是成功的)。比较一下。
$ grep -vE '^[.]' <<<$'.\na'; echo $?
a
0

使用

$ grep -vE '^[.]' <<<$'.\n.'; echo $?
1

请注意第一条命令输出了行a,这意味着它找到了匹配项,因此退出状态为0。与之相比,第二个示例没有匹配到任何行。 参考资料 <<<是Here字符串:
Here Strings
    A variant of here documents, the format is:

           [n]<<<word

    The word undergoes brace  expansion,  tilde  expansion,  parameter  and
    variable  expansion,  command  substitution,  arithmetic expansion, and
    quote removal.  Pathname expansion and  word  splitting  are  not  per-
    formed.   The  result  is  supplied  as a single string, with a newline
    appended, to the command on its standard input (or file descriptor n if
    n is specified).

   $ cat <<<'hello world'
   hello world

$'1\na'用于获取多行输入(\n$'string'中会被替换为新行符,更多信息请参阅man bash)。

$ echo $'1\na'
1
a

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接