Bash脚本陷入无限循环报错:循环执行目标脚本直至失败异常
解决Bash循环脚本无限循环及语法错误问题
需求说明
编写Bash脚本,循环执行一个偶尔会失败的目标脚本,直到该目标脚本失败为止。
目标脚本(偶尔失败)
#!/usr/bin/bash n=$(( RANDOM % 100 )) if (( n == 42 )) ; then echo "$n Something went wrong" >&2 echo "The error was using magic numbers" exit 1 fi echo "$n Everything went according to plan"
原脚本问题
用户编写的循环脚本存在语法错误和逻辑问题,运行时陷入无限循环,且提示第11行42 Something went wrong处语法错误:
#!/usr/bin/bash script_path="/tmp/missing/l2q3.sh" found=0 counter=0 while (( $found == 0 )); do output=(bash $script_path) if (( $output == 42 Something went wrong )); then found=1 fi ((counter++)) if (( $found == 1 )); then echo "Number 42 was found after $counter tries" fi done
问题分析
- 语法错误:
(( ... ))是Bash的算术运算判断结构,仅用于数值运算,不能用来做字符串匹配,用它判断$output == "42 Something went wrong"完全不符合语法规则。 - 输出捕获错误:
output=(bash $script_path)是将命令的每个输出单词拆分为数组元素,并没有正确捕获完整的标准输出内容。 - 逻辑冗余:目标脚本失败时会返回退出码
1,成功时返回0,完全可以通过退出码判断执行结果,无需依赖字符串匹配,原脚本舍近求远导致逻辑复杂且不可靠。 - 计数逻辑问题:原脚本的计数器递增时机和输出位置错误,导致统计次数不准确。
修正方案
方案1:利用退出码判断(推荐)
这是最简洁可靠的方式,直接通过目标脚本的退出码判断是否继续循环:
#!/usr/bin/bash script_path="/tmp/missing/l2q3.sh" counter=0 # 当脚本执行成功(退出码0)时继续循环,失败(退出码非0)时终止循环 while bash "$script_path"; do ((counter++)) done # 最后一次失败的执行也要计入次数 ((counter++)) echo "Number 42 was found after $counter tries"
方案2:匹配输出判断(不推荐,仅作演示)
如果一定要通过输出内容判断,需正确捕获输出并使用字符串比较结构:
#!/usr/bin/bash script_path="/tmp/missing/l2q3.sh" found=0 counter=0 while (( found == 0 )); do # 捕获目标脚本的标准输出到变量 output=$(bash "$script_path") ((counter++)) # 使用[[ ... ]]进行字符串精确匹配 if [[ "$output" == "42 Something went wrong" ]]; then found=1 echo "Number 42 was found after $counter tries" fi done
总结
- 优先使用命令的退出码判断执行结果,这是Shell脚本的标准规范,比字符串匹配更可靠。
- 字符串匹配需使用
[[ ... ]]结构,而非算术判断的(( ... ))。 - 捕获命令输出用
$()而非数组赋值,除非需要拆分输出的单词。
内容的提问来源于stack exchange,提问作者immaculatecapper
相关产品推荐
相关产品推荐

