【发布时间】:2022-09-24 20:57:16
【问题描述】:
为什么在 BASH 算术表达式 $((...)) 中执行错误的 HEX 转换会导致所有 while 循环中断?
例子:
#!/bin/bash
good_hex=\"ABCD\"
bad_hex=\"EFGH\"
while true;
do
echo \"Start 1\"
while true;
do
echo \"Start 2\"
# Convert Hex to Decimal
var1=$((16#$good_hex))
echo \"Good Hex: $var1\"
var2=$((16#$bad_hex))
echo \"Bad Hex: $var2\" # Won\'t be printed
echo \"End 2\" # Won\'t be printed
done
echo \"Exit 2\" # Won\'t be printed
echo \"End 1\" # Won\'t be printed
done
echo \"Exit 1\"
输出:
chris@ubuntu:~$ ./hex_breaks.sh
Start 1
Start 2
Good Hex: 43981
./hex_breaks.sh: line 15: 16#EFGH: value too great for base (error token is \"16#EFGH\")
Exit 1
在错误的十六进制转换之后,运行任何一个while循环都没有更多内容。执行的下一条语句是“Exit 1”(在所有 while 循环之外),然后程序终止。
作为比较,使用 \"let\" 命令而不是 $((...)) 会导致脚本正确运行并永远循环。
例子:
#!/bin/bash
good_hex=\"ABCD\"
bad_hex=\"EFGH\"
while true;
do
echo \"Start 1\"
while true;
do
echo \"Start 2\"
# Convert Hex to Decimal
let var1=16#$good_hex
echo \"Good Hex: $var1\"
let var2=16#$bad_hex
echo \"Bad Hex: $var2\" # Will be printed
echo \"End 2\" # Will be printed
done
echo \"Exit 2\"
echo \"End 1\"
done
echo \"Exit 1\"
输出:
chris@ubuntu:~$ ./hex_works.sh
Start 1
Start 2
Good Hex: 43981
./hex_works.sh: line 15: let: var2=16#EFGH: value too great for base (error token is \"16#EFGH\")
Bad Hex:
End 2
Start 2
Good Hex: 43981
./hex_works.sh: line 15: let: var2=16#EFGH: value too great for base (error token is \"16#EFGH\")
Bad Hex:
End 2
Start 2
Good Hex: 43981
./hex_works.sh: line 15: let: var2=16#EFGH: value too great for base (error token is \"16#EFGH\")
Bad Hex:
End 2
Start 2
Good Hex: 43981
./hex_works.sh: line 15: let: var2=16#EFGH: value too great for base (error token is \"16#EFGH\")
Bad Hex:
End 2
...
(Continues forever)
该脚本按预期运行,并且永远不会跳出 while 循环。
一些消息来源声称 \"let\" 和 $((...)) 是相同的。我的 lint 检查器说我应该使用 $((...)) 算术复合而不是 \"let\" 因为它更安全。然而,打破所有条件循环似乎是一个糟糕的操作完全出乎意料的副作用!
任何想法发生了什么?
-
类似于
while true; do; : \"${1a}\"; done?