GitLab CI Job中Bash if语句执行结果不符合预期问题
问题原因
- 跨平台
expr实现差异:你本地Mac设备预装的是BSD版本expr,而GitLab CI Runner默认运行在Linux环境,使用GNU版本expr,两者语法不兼容:- GNU版本
expr不支持match参数后的逗号分隔写法,你脚本中写的逗号会被识别为入参的一部分,导致所有版本号都匹配失败,永远返回0 - GNU版本
expr的match逻辑在正则包含捕获组()时,会返回第一个捕获组的内容而非匹配长度,你的正则带3个捕获组,即使去掉逗号,返回值也不是你预期的匹配长度,会导致判断逻辑错误
- GNU版本
- 额外隐性坑:如果GitLab CI执行脚本的默认shell是
sh而非bash,部分bash特有的语法也可能出现执行异常
修复方案
推荐直接使用bash内置正则匹配,不依赖外部expr命令,避免跨平台兼容问题,修改后的script段如下:
script: - echo $NEW_VERSION - export STAGE=staging - |- # 内置正则匹配,仅纯x.y.z格式的正式版本触发STAGE修改 if [[ $NEW_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then export STAGE=production; fi - echo $STAGE
如果需要兼容sh环境(比如CI默认shell为sh),可以用兼容性更强的case写法,逻辑更直观:
script: - echo $NEW_VERSION - export STAGE=staging - |- case "$NEW_VERSION" in # 匹配所有带develop后缀的先行版本,保持STAGE为staging *-develop*) ;; # 匹配正式版本,修改STAGE为production [0-9]*.[0-9]*.[0-9]*) export STAGE=production ;; esac - echo $STAGE
内容的提问来源于stack exchange,提问作者Markus
相关产品推荐
相关产品推荐

