You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins Pipeline中无法运行Shell脚本的问题求助

解决Jenkins Pipeline中测试覆盖率检查的脚本错误

错误原因分析

  1. 第一个错误(非法$字符):
    Groovy在双引号字符串中会自动解析$作为变量引用的起始符,你sed命令里的正则结尾$被Groovy误判成了变量定义的开头;同时sed的反向引用\2在双引号中会被Groovy转义成普通字符2,导致sed无法识别。

  2. 第二个错误(unexpected token: s):
    用单引号包裹整个脚本时,脚本内部的单引号没有转义,Groovy会把'sed -nE '后面的s当成独立代码块,触发语法错误。


解决办法

推荐三种可行的修正方式,按易用性排序:

方式1:使用单引号三引号包裹脚本(最省心)

Groovy的单引号三引号(''')会将内部内容完全作为字面量传递,无需转义任何字符:

stage('Test Coverage'){
    steps {
        echo "Running test"
        sh "mvn test"
        script{
            TOTAL_COVERAGE_STR = sh (
                script: '''sed -nE 's/^.*<td>Total<([^>]+>){4}([^<]*).*$/Missed instructions: \2/p' target/site/jacoco/index.html | tr -dc '0-9.' ''',
                returnStdout: true
            ).trim()
            THRESHOLD = 12.00
            Float TOTAL_COVERAGE = TOTAL_COVERAGE_STR as Float
            echo "Total Coverage : ${TOTAL_COVERAGE}, Threshold: ${THRESHOLD}"
            if (THRESHOLD > TOTAL_COVERAGE) {
                error('Aborting the build, as The Test Coverage Is Not As Expected')
            }
        }
    }
}

方式2:使用单引号包裹脚本,内部单引号转义

在Groovy单引号字符串中,用两个连续单引号('')表示一个字面单引号:

TOTAL_COVERAGE_STR = sh (
    script: 'sed -nE ''s/^.*<td>Total<([^>]+>){4}([^<]*).*$/Missed instructions: \2/p'' target/site/jacoco/index.html | tr -dc ''0-9.''',
    returnStdout: true
).trim()

方式3:使用双引号包裹脚本,转义$和反向引用

给sed里的$加\转义,反向引用\2要写成\\2(Groovy会先解析一层转义):

TOTAL_COVERAGE_STR = sh (
    script: "sed -nE 's/^.*<td>Total<([^>]+>){4}([^<]*).*\\\$/Missed instructions: \\\\2/p' target/site/jacoco/index.html | tr -dc '0-9.'",
    returnStdout: true
).trim()

另外,优化了tr命令的参数,把重复的0-9.0-9改成0-9.,功能完全一致且更简洁。

内容的提问来源于stack exchange,提问作者Prarabdh Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 11:10:43