Shell/Zsh脚本中字符串转浮点数比较失效问题求助
解决Shell/Zsh中版本号(字符串转浮点数)比较失效的问题
问题原因
原脚本使用-gt整数比较运算符处理带小数点的版本号,这是错误的:
- 在sh中,
-gt无法解析非整数,会触发非预期的字符串比较或默认值处理,导致结果错误; - 在zsh中,虽然支持浮点数比较,但像
2.10.0这类多小数点的版本号不是合法浮点数,直接比较会抛出bad floating point constant错误。
解决方案
方法1:使用GNU sort的版本排序(推荐)
利用sort -V(版本号排序)特性,自动处理不同格式的版本号(如2.40和2.38.0),通过检查排序结果判断版本大小:
REQUIRED_VERSION=2.38.0 VERSION=$(echo "$FULL_DATA" | cut -d ":" -f 5) # 判断VERSION是否严格大于REQUIRED_VERSION if [ "$(printf "%s\n%s\n" "$REQUIRED_VERSION" "$VERSION" | sort -V | tail -n1)" = "$VERSION" ] && [ "$VERSION" != "$REQUIRED_VERSION" ]; then echo "=== PASSED ==== " else echo "=== FAILED ===" # exit 1 fi
方法2:手动转换版本号为整数(兼容性更强)
将版本号的每个分段补零对齐后拼接成整数,再用整数比较,适合不支持sort -V的环境:
# 转换版本号为对齐的整数(如2.10.0 → 002010000,2.40 → 002040000) convert_version() { local ver=$1 # 分割版本号为分段,补零到3位后拼接 printf "%03d%03d%03d" $(echo "$ver" | tr '.' ' ') } REQUIRED_VERSION=2.38.0 VERSION=$(echo "$FULL_DATA" | cut -d ":" -f 5) REQUIRED_NUM=$(convert_version "$REQUIRED_VERSION") VERSION_NUM=$(convert_version "$VERSION") if [ "$VERSION_NUM" -gt "$REQUIRED_NUM" ]; then echo "=== PASSED ==== " else echo "=== FAILED ===" # exit 1 fi
说明
- 方法1依赖GNU sort(大部分Linux系统默认支持),代码简洁,能处理绝大多数语义化版本号;
- 方法2兼容性更好,可适配BSD等无
sort -V的环境,若版本号分段超过3位,可调整printf中的补零位数(如%04d)。
内容的提问来源于stack exchange,提问作者Shubham Jain
相关产品推荐
相关产品推荐

