Jenkinsfile中Bash脚本的sed命令转义失败问题求助
Jenkinsfile中Bash脚本sed转义引发语法错误的解决办法
问题重现
把本地运行正常的Bash脚本放到Jenkinsfile的sh块中执行时,「Update Cloudfront」阶段触发语法错误,报错信息如下:
WorkflowScript: 73: unexpected char: '\\' @ line 73, column 113. cidr $YAML_FILE | sed -E \"s/\,37\.16\. ^
尝试过多种转义方式和引号切换均无法解决。
解决方法
方法一:简化sed命令,减少转义冲突
问题根源在于sed命令里的多余转义和分隔符选择,直接修改sed命令即可:
- 逗号在sed替换表达式中不属于特殊字符,无需转义,去掉
\,中的反斜杠 - 将sed的替换分隔符从
/换成#,避免转义IP地址里的/,减少反斜杠使用量
修改后的Jenkinsfile代码:
stage('Update Cloudfront'){ steps { sh ''' #!/bin/bash YAML_FILE="path/to/values.yaml" DATE="$(date '+%d-%m-%Y')" wget https://www.cloudflare.com/ips-v4 && wget https://www.cloudflare.com/ips-v6 CLOUDFLARE_NEW=$(awk '{printf fmt,$1}' fmt="%s\n" ips-v4 ips-v6 | paste -sd, -) # 修改后的sed命令 CLOUDFLARE_OLD=$(yq -r .controller.config.proxy-real-ip-cidr $YAML_FILE | sed -E 's#,37\.16\.11\.30/32##') if [[ "$CLOUDFLARE_NEW" == "$CLOUDFLARE_OLD" ]]; then echo "No need to do anything" else echo "Cloudflare IP ranges change detected, updating Nginx value file" CLOUDFLARE_NEW=$(awk '{printf fmt,$1}' fmt="%s\n" ips-v4 ips-v6 | paste -sd, -) yq e '.controller.config.proxy-real-ip-cidr = env(CLOUDFLARE_NEW)' -i $YAML_FILE echo "Add third party IP range" yq e '.controller.config.proxy-real-ip-cidr += ",1.2.3.4/32"' -i $YAML_FILE fi ''' } }//end stage('Update Cloudfront')
方法二:将脚本独立为文件(更推荐)
如果不想在Jenkinsfile中纠结转义问题,可以把脚本保存为独立的bash文件(比如update_cloudflare.sh),内容和本地运行的版本完全一致:
#!/bin/bash YAML_FILE="path/to/values.yaml" DATE="$(date '+%d-%m-%Y')" wget https://www.cloudflare.com/ips-v4 && wget https://www.cloudflare.com/ips-v6 CLOUDFLARE_NEW=$(awk '{printf fmt,$1}' fmt="%s\n" ips-v4 ips-v6 | paste -sd, -) CLOUDFLARE_OLD=$(yq -r .controller.config.proxy-real-ip-cidr $YAML_FILE | sed -E 's/\,37\.16\.11\.30\/32//') if [[ "$CLOUDFLARE_NEW" == "$CLOUDFLARE_OLD" ]]; then echo "No need to do anything" else echo "Cloudflare IP ranges change detected, updating Nginx value file" CLOUDFLARE_NEW=$(awk '{printf fmt,$1}' fmt="%s\n" ips-v4 ips-v6 | paste -sd, -) yq e '.controller.config.proxy-real-ip-cidr = env(CLOUDFLARE_NEW)' -i $YAML_FILE echo "Add third party IP range" yq e '.controller.config.proxy-real-ip-cidr += ",1.2.3.4/32"' -i $YAML_FILE fi
然后在Jenkinsfile中调用该文件:
stage('Update Cloudfront'){ steps { sh 'chmod +x update_cloudflare.sh' sh './update_cloudflare.sh' } }//end stage('Update Cloudfront')
这种方式完全规避了Jenkinsfile中的转义冲突,脚本逻辑和本地保持一致,后续维护也更方便。
内容的提问来源于stack exchange,提问作者DisplayName
相关产品推荐
相关产品推荐

