为何Shell脚本未在预期错误场景下触发报错?
问题
当merge_marketable_count数值明显小于marketable_count时,运行以下Shell脚本却未触发错误数组输出和退出状态,不符合预期:
#!/bin/bash # Sample local values merge_marketable_count=0 marketable_count=200 countDifference=95/100 # This still assigns the string "95/100" to countDifference. merge_opt_out_count=50 opt_out_count=60 total_merge_count=500 total_count=550 errorArray=() if [ "$merge_marketable_count" -lt "$(( marketable_count * ${countDifference} ))" ]; then marketable_message="The total Marketable counts within our EMU table is greater than 5%, merge=$merge_marketable_count, view=$marketable_count and CountDiffUsed=${countDifference}" echo $marketable_message errorArray+=("$marketable_message") fi if [ ${#errorArray[@]} -gt 0 ]; then echo "error array" echo "${#errorArray[@]}" exit 1 fi
问题原因
- 字符串赋值导致运算错误:
countDifference=95/100只是把字符串"95/100"赋值给变量,不是计算后的0.95。在$(( marketable_count * ${countDifference} ))里,Shell会把"95/100"当作整数除法处理,结果是0(Shell整数除法会直接舍去小数)。此时判断条件变成0 -lt 0,不成立,自然不会触发错误逻辑。 - Shell整数运算限制:
$((...))只支持整数运算,没法直接处理浮点数比较,这也是导致比例计算失效的核心原因。
修复方案
方案1:用bc处理浮点数比较
借助bc工具实现浮点数运算和比较,这样能准确判断比例差异:
#!/bin/bash # 示例值 merge_marketable_count=0 marketable_count=200 countDifference=0.95 # 直接用小数表示95%的比例 merge_opt_out_count=50 opt_out_count=60 total_merge_count=500 total_count=550 errorArray=() # 通过bc计算浮点数,返回1表示条件成立,0表示不成立 if [ $(echo "$merge_marketable_count < $marketable_count * $countDifference" | bc -l) -eq 1 ]; then marketable_message="EMU表中可营销总数差异超过5%,merge=$merge_marketable_count, view=$marketable_count,使用的差异比例=${countDifference}" echo "$marketable_message" errorArray+=("$marketable_message") fi if [ ${#errorArray[@]} -gt 0 ]; then echo "错误数组内容:" echo "${errorArray[@]}" exit 1 fi
方案2:转成整数比例运算(避免浮点数)
把百分比转换为整数运算,比如95%等价于marketable_count * 95 / 100,用整数运算就能实现需求:
#!/bin/bash # 示例值 merge_marketable_count=0 marketable_count=200 countDifference=95 # 用整数表示百分比,95即95% merge_opt_out_count=50 opt_out_count=60 total_merge_count=500 total_count=550 errorArray=() # 整数运算计算marketable_count的95%,再做比较 if [ "$merge_marketable_count" -lt $(( marketable_count * countDifference / 100 )) ]; then marketable_message="EMU表中可营销总数差异超过5%,merge=$merge_marketable_count, view=$marketable_count,使用的差异比例=${countDifference}%" echo "$marketable_message" errorArray+=("$marketable_message") fi if [ ${#errorArray[@]} -gt 0 ]; then echo "错误数组内容:" echo "${errorArray[@]}" exit 1 fi
内容的提问来源于stack exchange,提问作者AnthonyEdwardsStan
相关产品推荐
相关产品推荐

