Bash在执行数值计算时退出
我试图在bash脚本中执行以下逻辑Bash在执行数值计算时退出,bash,shell,sh,Bash,Shell,Sh,我试图在bash脚本中执行以下逻辑 #!/bin/bash set -x # Copy merchant files set -o pipefail -o errexit a=0 b=0 c=$(expr $a + $b) if [[ $(expr $c) -lt 10 ]]; then echo true fi 这永远不会像预期的那样真实。产出为: ++ set -o pipefail -o errexit ++ a=0 ++ b=0 +++ expr 0 + 0 ++ c=0 此外
#!/bin/bash
set -x
# Copy merchant files
set -o pipefail -o errexit
a=0
b=0
c=$(expr $a + $b)
if [[ $(expr $c) -lt 10 ]]; then
echo true
fi
这永远不会像预期的那样真实。产出为:
++ set -o pipefail -o errexit
++ a=0
++ b=0
+++ expr 0 + 0
++ c=0
此外,当a和b都为0时,上述逻辑不起作用,如果其中任何一个为非零,则工作正常。如果我修改了我的逻辑,而不是计算c,那么直接在if中使用expr,如果它工作良好,并且按照预期打印true,而不考虑a和b的值
#!/bin/bash
set -x
# Copy merchant files
set -o pipefail -o errexit
a=0
b=0
if [[ $(expr $a + $b) -lt 10 ]]; then
echo true
fi
有人能解释一下第一段代码有什么问题吗。问题是,如果算术表达式的计算结果为零,它将返回非零退出状态(shell将其解释为错误)。这与设置-o errexit
不立即兼容
因为您使用的是Bash,所以简单的解决方法是根本不使用expr
c=$((a + b))
if [[ "$c" -lt 10 ]]; then
echo true
fi
如果出于某种原因希望继续使用expr
,习惯用法是使用| | true
或某种变体来捕获您希望允许的错误
c=$(expr "$a" + "$b") || true
当您将计算重构为if
子句时,这是“某种变体”,即errexit
无法在if
或while
子句的条件部分发生故障时触发(显然;否则,无法在set-o errexit
下编写带条件的代码).错误在于,如果算术表达式的计算结果为零,则将返回非零退出状态(shell将其解释为错误)。这与设置-o errexit
不立即兼容
因为您使用的是Bash,所以简单的解决方法是根本不使用expr
c=$((a + b))
if [[ "$c" -lt 10 ]]; then
echo true
fi
如果出于某种原因希望继续使用expr
,习惯用法是使用| | true
或某种变体来捕获您希望允许的错误
c=$(expr "$a" + "$b") || true
当您将计算重构为
if
子句时,这是“某种变体”,即errexit
不能在if
或while
子句的条件部分发生故障时触发(显然;否则,就不可能在set-o errexit
下编写带条件的代码)。不是这样的“崩溃”,就是“退出”。你为什么要用expr
做算术?c=$((a+b))
和if[[$c-lt 10]
工作正常。不是“崩溃”,而是“退出”。你为什么要用expr
做算术?c=$(a+b))
和if[$c-lt 10]]
工作正常。实际使用c=$((a+b))
甚至((c=a+b))
比使用非内置的expr
in更有效。我建议不要使用-o errexit
,因为这样可能会遇到意外的脚本终止。是的,如果可以,请避免expr
。我不同意对set-o errexit
akaset-e
的警告,但您需要了解何时终止有用,然后如何正确使用。我个人更喜欢显式错误处理而不是隐式错误处理。主要是因为退出代码不仅用于报告错误,还用于返回逻辑状态(请参见grep
,diff
,cmp
,ps
,kill
,expr
等)。事实上,expr
对我来说是新的。;)我不知道你为什么要反对errexit
-意外的脚本执行可能会更糟。c=$((a+b))
甚至是POSIX的一部分(尽管((c=a+b))
仍然是一种巴什主义)。实际上使用c=$((a+b))
,甚至((c=a+b))
比使用非内置的expr
in更有效。我建议不要使用-o errexit
,因为这样可能会遇到意外的脚本终止。是的,如果可以,请避免expr
。我不同意对set-o errexit
akaset-e
的警告,但您需要了解何时终止有用,然后如何正确使用。我个人更喜欢显式错误处理而不是隐式错误处理。主要是因为退出代码不仅用于报告错误,还用于返回逻辑状态(请参见grep
,diff
,cmp
,ps
,kill
,expr
等)。实际上,expr
对我来说是新的。;)我不知道你为什么会建议不要errexit
-意外的脚本执行可能会更糟。c=$((a+b))
甚至是POSIX的一部分(尽管((c=a+b))
仍然是一种巴西主义)。