iag*_*ito 67 grep bash exit error-handling
此脚本不回显“之后”:
#!/bin/bash -e
echo "before"
echo "anything" | grep e # it would if I searched for 'y' instead
echo "after"
exit
Run Code Online (Sandbox Code Playgroud)
如果我删除了-eshebang 行上的选项,它也会如此,但我希望保留它,以便我的脚本在出现错误时停止。我不认为 grep 找不到匹配项是错误。我怎样才能防止它突然退出?
小智 70
echo "anything" | { grep e || true; }
Run Code Online (Sandbox Code Playgroud)
解释:
$ echo "anything" | grep e
### error
$ echo $?
1
$ echo "anything" | { grep e || true; }
### no error
$ echo $?
0
### DopeGhoti's "no-op" version
### (Potentially avoids spawning a process, if `true` is not a builtin):
$ echo "anything" | { grep e || :; }
### no error
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)
“||” 表示“或”。如果命令的第一部分“失败”(意思是“grep e”返回非零退出代码),则“||”之后的部分 被执行,成功并返回零作为退出代码(true总是返回零)。
小智 35
一种安全且可选的 grep消息的可靠方法:
echo something | grep e || [[ $? == 1 ]] ## print 'something', $? is 0
echo something | grep x || [[ $? == 1 ]] ## no output, $? is 0
echo something | grep --wrong-arg e || [[ $? == 1 ]] ## stderr output, $? is 1
Run Code Online (Sandbox Code Playgroud)
根据posix 手册,退出代码:
1 表示未选择任何行。> 1 表示错误。roe*_*eer 17
另一种选择是向管道添加另一个命令 - 一个不会失败的命令:
echo "anything" | grep e | cat
因为cat现在是管道中的最后一个命令,它的退出状态cat,没有的grep,将被用来确定管道失败与否。
Wad*_* M. 12
如果您正在使用 grepset -euo pipefail并且不想在未找到记录的情况下退出(退出代码 = 1),但如果它是另一个退出代码,仍然希望它失败,您可以使用:
#!/bin/bash
set -euo pipefail
echo "anything" | { grep e || test $? = 1; } | { grep e2 || test $? = 1; }
Run Code Online (Sandbox Code Playgroud)
管道内的 grep 只会忽略退出状态 = 1。这样你就不需要失去使用set -euo pipefail.
在这个例子中,我特意包含了两个可能无法说明这个概念的管道 grep。
请参阅 myrdd 在那里的帖子。
#!/bin/bash -e
echo "before"
echo "anything" | grep e || : # it would if I searched for 'y' instead
echo "after"
exit
Run Code Online (Sandbox Code Playgroud)
set -e 或者 set -o errexit
如果管道(可能由单个简单命令组成)、列表或复合命令(见
SHELL GRAMMAR上文)以非零状态退出,则立即退出。如果失败的命令是紧跟在所述命令列表的一部分的壳不退出while或until关键字,继该测试的一部分if或elif保留字,在执行任何命令的一部分&&或||除命令列表以下的最终&&或||,任何命令在管道中但最后一个,或者如果命令的返回值被反转!. 如果子shell 以外的复合命令由于命令在-e被忽略时失败而返回非零状态,则shell 不会退出。ERR如果设置了一个陷阱,则在 shell 退出之前执行。这个选项适用于shell环境和每个子?单独的 shell 环境(见COMMAND EXECUTION ENVIRONMENT上文),并且可能导致子 shell 在执行子 shell 中的所有命令之前退出。
另外,:是 Bash 中的无效命令。