为什么while循环中的语法错误会中断脚本(但在while循环之外不会)



考虑以下三个bash脚本:

  • 脚本没有语法错误-执行没有错误,如预期,循环"这是结束:-1":
#!/bin/bash
while true ; do
x=1 # or, read the variable from some external source
y=2 # or, read the variable from some external source
z=$(( $x - $y ))
echo "this is the result: $z"
sleep 1
done

执行-无限循环,直到我们中断:

$ bash test.sh
this is the result: -1
this is the result: -1
this is the result: -1
^C
  • 脚本导致语法错误(注意缺少x和y变量,然后需要进行计算):
#!/bin/bash
while true ; do
x= # or, read the variable from some external source
y= # or, read the variable from some external source
z=$(( $x - $y ))
echo "this is the result: $z"
sleep 1
done

执行- bash在出现语法错误时中断脚本执行:

$ bash test.sh
test.sh: line 6: -  : syntax error: operand expected (error token is "-  ")
  • 脚本没有while循环-脚本执行不中断:
#!/bin/bash
x=
y=
z=$(( $x - $y ))
echo "this is the result: $z"

Execution - bash注意到计算中的语法错误,但不会中断脚本的执行:

$ bash test.sh
test.sh: line 5: -  : syntax error: operand expected (error token is "-  ")
this is the result:

为什么bash在获得语法错误时的行为不同,取决于它是否在while循环中?编辑:我知道输入变量可以/应该被验证,有各种方法可以做到这一点。我更感兴趣的是为什么它的行为不同,这取决于我们是否在while循环中。

区别不在于是否在循环中;不同之处在于变量为空。

$ bash  # start a fresh instance
bash$ x=''
bash$ y=''
bash$ $(( $x - $y ))
bash: -  : syntax error: operand expected (error token is " ")

@oguzismail在注释中指出,语法错误实际上不会导致整个脚本退出;它导致复合命令(即while循环)中止。您可以通过在done行之后添加echo "still here"来演示这一点。

如果你想防止这种情况发生,当你收到xy从外部来源,也许检查他们是否包含任何非数字字符?

case ${x#-}${y#-} in
*[!0-9]*)
echo "$0: error; $x and $y need to be strictly numeric" >&2
exit 74;;
esac

请注意,如果通过参数展开的方式存在,则可以删除单个减号。

正如@ l逍遥指出的,在Bash中,您也可以简单地说declare -i x y,让shell将xy的可能值约束为整数;如果它们接收到无效的值,它们将被强制转换为0

最新更新