Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash在执行数值计算时退出_Bash_Shell_Sh - Fatal编程技术网

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 此外

我试图在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
此外,当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
aka
set-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
aka
set-e
的警告,但您需要了解何时终止有用,然后如何正确使用。我个人更喜欢显式错误处理而不是隐式错误处理。主要是因为退出代码不仅用于报告错误,还用于返回逻辑状态(请参见
grep
diff
cmp
ps
kill
expr
等)。实际上,
expr
对我来说是新的。;)我不知道你为什么会建议不要
errexit
-意外的脚本执行可能会更糟。
c=$((a+b))
甚至是POSIX的一部分(尽管
((c=a+b))
仍然是一种巴西主义)。