为何Bash脚本出现‘value too great for base’错误,交互Shell却正常?
问题描述
需要检查某个外部传入的字符串是否为关联数组的键,数组声明如下:
declare -A TARGETS=( [mystring1]=mystring [otherstring1]=otherstring [lastone]=lastone )
脚本中通过以下代码获取参数并移除引号:
DB=$(sed -e "s/^'//" -e "s/'$//" <<<"$3")
之后用这段代码判断键是否存在:
if [ -z "${TARGETS[$DB]}" ]; then # shellcheck disable=SC2154 for URI in "${TARGETS[@]}" do do_update done else URI="${DB}" do_update fi
当DB的值为tags/06/02/2023T105941时,脚本报错:
line 40: tags/06/02/2023T105941: value too great for base (error token is "2023T105941")
报错行正是上述的判断语句,但在同一机器的交互Shell中执行类似代码却能正常运行。
问题原因与解决方法
核心原因
你的脚本大概率是用#!/bin/sh作为解释器开头,或者被用sh命令执行了。多数系统里的sh是dash这类不支持bash关联数组特性的Shell,此时declare -A TARGETS的声明会被忽略,数组被当作普通索引数组处理。
当普通索引数组使用字符串作为下标时,Shell会尝试将这个字符串解析为算术表达式来计算索引值。比如tags/06/02/2023T105941会被当成除法运算,但字符串里的2023T105941包含非数字字符T,导致算术求值失败,触发报错。而交互Shell通常是bash,支持关联数组,所以字符串会被直接当作键名处理,不会报错。
解决方法
- 修改脚本开头的解释器:将脚本第一行改为
#!/bin/bash,确保脚本用bash执行。 - 正确执行脚本:如果之前用
sh yourscript.sh执行,改成bash yourscript.sh。 - 验证关联数组生效:可以在脚本开头添加
declare -p TARGETS,确认数组被正确声明为关联数组(输出会包含declare -A TARGETS=...)。
内容的提问来源于stack exchange,提问作者Simon Vart
相关产品推荐
相关产品推荐

