对于多个命令,是否有类似于pipefail的东西,比如'try'语句,但在bash中。我想这样做:
echo "trying stuff"
try {
command1
command2
command3
}
在任何时候,如果任何命令失败了,就退出并回显该命令的错误。我不想做这样的事情:
command1
if [ $? -ne 0 ]; then
echo "command1 borked it"
fi
command2
if [ $? -ne 0 ]; then
echo "command2 borked it"
fi
等等……或者类似的事情:
pipefail -o
command1 "arg1" "arg2" | command2 "arg1" "arg2" | command3
因为我相信每个命令的参数(如果我错了请纠正我)会相互干扰。这两种方法对我来说似乎非常冗长和讨厌,所以我在这里呼吁一种更有效的方法。
你说的“退出并回复错误”是什么意思?如果您的意思是希望脚本在任何命令失败时立即终止,那么就这样做
set -e # DON'T do this. See commentary below.
在脚本的开头(但注意下面的警告)。不要回显错误消息:让失败的命令处理它。换句话说,如果你这样做:
#!/bin/sh
set -e # Use caution. eg, don't do this
command1
command2
command3
而command2失败,同时打印一个错误消息到stderr,那么似乎您已经实现了您想要的。(除非我误解了你想要的!)
因此,您编写的任何命令都必须表现良好:它必须向stderr而不是stdout报告错误(问题中的示例代码将错误输出到stdout),并且在失败时必须以非零状态退出。
However, I no longer consider this to be a good practice. set -e has changed its semantics with different versions of bash, and although it works fine for a simple script, there are so many edge cases that it is essentially unusable. (Consider things like: set -e; foo() { false; echo should not print; } ; foo && echo ok The semantics here are somewhat reasonable, but if you refactor code into a function that relied on the option setting to terminate early, you can easily get bitten.) IMO it is better to write:
#!/bin/sh
command1 || exit
command2 || exit
command3 || exit
or
#!/bin/sh
command1 && command2 && command3
另一种方法是简单地将命令与&&连接在一起,这样第一个失败的命令就会阻止其他命令的执行:
command1 &&
command2 &&
command3
这不是您在问题中要求的语法,但它是您所描述的用例的通用模式。一般来说,这些命令应该负责打印失败,这样您就不必手动执行了(当您不想要错误时,可以使用-q标志来屏蔽错误)。如果您有修改这些命令的能力,我会将它们编辑为在失败时大喊,而不是将它们包装在具有这种功能的其他东西中。
还要注意,你不需要这样做:
command1
if [ $? -ne 0 ]; then
你可以简单地说:
if ! command1; then
当你确实需要检查返回码时,使用算术上下文而不是[…]- ne:
ret=$?
# do something
if (( ret != 0 )); then