BASH 管道退出代码

BASH 管道退出代码

我正在编写一个简单的脚本,用于检查命令输出中的某个关键字。为了查看它是否有效,我从 bash 命令行检查了该命令。

$ ls | grep -q foo
$ echo $?

它显示 1 或 0,具体取决于命令输出和预期的 grep 参数。

我厌倦了重新输入命令,所以我| echo $?在命令行末尾添加了。

$ ls | grep -q foo | echo $?

然后,无论命令输出如何,它总是返回 0,即使第一部分应该返回 1。

我猜这是正常行为,但我想知道为什么 bash 以这种方式工作。

答案1

这是因为管道采用标准输出并将其通过管道传输到下一个命令,而您想要的是分号。

ls | grep -q foo; echo $?

这样就完成了lsgrep命令,然后执行echo命令。

答案2

$ ls | grep -q foo | echo $?

然后,无论命令输出如何,它总是返回 0,即使第一部分应该返回 1。

更准确地说,echo $?此管道中的将打印管道之前执行的前一个命令的退出代码。在此示例中,它将输出 7:

( exit 7 )
ls / | grep . | echo $?

ls | grep -q foo | echo $?在命令行上输入并按下回车键后,将会发生以下事情(其中包括):

  • shell 解析并解释命令行。
    • $?它用您按下回车键之前执行的前一个命令的退出代码替换变量。
    • 例如,如果前一个命令以 7 退出,则 shell 认为要执行的命令是ls | grep -q foo | echo 7
  • 它执行该命令。

换句话说,当您按下 Enter 键执行管道时ls | grep -q foo | echo $?,shell 会解析并解释它收到的行,并$?在开始执行管道中的命令之前评估变量。


相关说明一下,您可以在条件语句中直接使用退出代码,例如:

if ls | grep -q foo; then echo success, there is foo; fi

或者,如果您想在成功时执行某些操作,则可以使用以下命令链接下一个命令&&

ls | grep -q foo && echo success

相关内容