bash - 进入 grep -v 时获取退出代码

标签 bash grep exit-code

<分区>

我有一个这样的脚本:

#!/bin/sh

echo "hello"
echo "goodbye"
exit 1

当我单独运行它时,我得到了预期的失败退出代码。

$ ./fail.sh
hello
goodbye
$ echo $?
1

但是,当我通过 grep -v 运行它时,退出状态变为成功:

$ ./fail.sh | grep -v hello
goodbye
$ echo $?
0

有没有一种方法可以将命令的输出通过管道传输到 grep -v 并且仍然可以正确传播状态代码?当然,在现实世界中,这样做的目的是过滤嘈杂命令的输出,同时仍然检测命令是否失败。

最佳答案

利用 set -o pipefail,以下应该可以工作:

( set -o pipefail; ./fail.sh | grep -v hello )

然后您可以测试 $? 中的值:

( set -o pipefail; ./fail.sh | grep -v hello ); if [[ "$?" -eq "1" ]]; then echo success; else echo bummer; fi 

它应该输出:

goodbye
success

发生了什么,为什么会这样?

如 OP 中所述,如果最后一个命令出错,管道通常只会返回失败(非零返回代码)。如果管道中的任何命令出错,使用 set -o pipefail 会导致命令管道产生失败返回代码。管道传递的失败返回码是最后失败命令的返回码。

您可以通过将脚本更新为:

来测试它:
#!/bin/sh

echo "hello"
echo "goodbye"
exit 5

然后运行以下命令:

( set -o pipefail; ./fail.sh | grep -v hello ); echo $?

它应该输出:

goodbye
5

上面说明 set -o pipefail 不仅以非零返回码退出,而且它正在逐字传递最后一个非零返回码。

关于bash - 进入 grep -v 时获取退出代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37126964/

相关文章:

Python 子进程 - mps-Youtube

linux - 仅杀死特定 Java jar 的进程(实例)

php - 从 PHP 脚本运行 bash 脚本

awk - bash 计数数字的数量

linux - 如何从 wget 输出中获取下载速度?

bash - 从命名管道捕获非零退出代码

bash - 从 bash 脚本采购时如何保持冗长

bash - bash if 语句中的错误 : Conditional binary operator expected

perl - 如何在 Perl 中同时捕获 stderr、stdout 和退出代码?

windows - Windows命令行命令的强制退出代码为零