Shell 数字校验:限制格式并避免前导零的进制误解
限制分钟数文本的字符和长度,再按十进制转换,拒绝越界与多余字符,避免直接计算未经验证的表达式。
本节目标
限制分钟数文本的字符和长度,再按十进制转换,拒绝越界与多余字符,避免直接计算未经验证的表达式。
环境与运行方法
使用 Bash 3.2 及以上,保存为 lesson.sh,执行 bash -n lesson.sh 检查语法,再运行 bash lesson.sh。不要使用 sh 替代 Bash,本组使用部分 Bash 专有语法。
核心思路
Bash 算术中的前导零可能触发八进制解释。先限定为一到四位 ASCII 数字,再使用十进制前缀转换,最后检查 1440 上限,能让格式和数值范围各自明确。
完整示例
for text in 08 0 1441 12x; do
if [[ ! $text =~ ^[0-9]{1,4}$ ]]; then
printf 'invalid\n'
continue
fi
value=$((10#$text))
if (( value <= 1440 )); then
printf 'ok=%s\n' "$value"
else
printf 'invalid\n'
fi
done预期输出
ok=8
ok=0
invalid
invalid逐步理解
08 通过格式验证后转为十进制 8。1441 是有效整数但超过业务上限,12x 在算术前被拒绝,零正常保留。先验证再计算,避免文本意外成为算术语法的一部分。
本协议不接受正负号、空白和小数。长度限制也让数值规模可控,即使 00000 数值上是零,仍因格式超长而失败。是否允许这些表示形式,应由数据协议决定。
常见问题与边界
- 不可信表达式不能直接送入算术求值。
- 格式正确不等于业务范围正确。
- 前导零不能默认按十进制理解。
动手练习
测试 1440、-1 和 0000。
参考答案
1440 和四个零合法,得到 1440 与 0;负号不符合格式,-1 被拒绝。支持符号需要重新定义并测试输入规则。
文章回复
0 条公开回复