shell 中 "grep" 的异常链接

unusual chaining of "grep" in the shell

我偶然发现了一条看起来很奇怪的 shell 指令:
ls -a | grep ".qmail-" | grep -v "mail" | grep ".mail" > t ; echo $?
我怀疑返回值代表错误。任何人都可以确认这一点或解释在什么情况下会应用该指令吗?

第一个 grep 只允许通过包含 qmail 的行(前面是任何字符,后面是破折号,但这在很大程度上是无关紧要的)。第二个 grep 删除包含 mail 的行,这意味着第一个 grep 通过的每一行都被第二个删除。第三个文件没有任何要处理的内容,因此文件 t 将始终为空。 $? 的值应为 1,失败,因为第三个 grep 未能找到与其模式匹配的任何行(因为它没有要处理的行)。

这是一个错误。

很难知道如何在不知道它正在尝试做什么的情况下修复它。

bash shell(以及大多数其他 shells)让用户可以使用一个命令的输出作为另一个命令的输入。这是通过称为管道的 | 运算符完成的。所以 ls -a 的输出被馈送到 grep ".qmail-" 等等。 > 运算符将命令的输出发送到文件,在本例中为 t。因此 ls -a | grep ".qmail-" | grep -v "mail" | grep ".mail" > t 列出目录的内容并通过连续的过滤器传递输出,最后将输出保存到文件 t.

分号表示命令结束,允许在一行中输入多个 bash 命令。

echo $? 打印出最后执行命令的 return 值,在本例中为 ls -a | grep ".qmail-" | grep -v "mail" | grep ".mail" > t。按照惯例,0 以外的任何值都表示发生了某种错误。The Linux Documentation Project 给出了一些常见退出代码的列表。