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

Jenkinsfile中Bash脚本无法替换Groovy变量的问题求助

问题:Jenkinsfile中Groovy变量无法在多行shell脚本中读取

在基于Groovy的Jenkinsfile中,尝试将变量build_tag代入shell脚本作为Docker容器名称时,脚本内部始终无法读取该变量值,但脚本前后的语句都能正常输出变量内容。已尝试用双引号包裹${hub_org}/player:${build_tag}、将字符串存入变量后替换等方法,均无效。

相关代码片段

Jenkinsfile核心代码

stage('Snyk Scan') {
    if (params.buildDockerImage == 'true') {
        println(ANSI_BOLD + ANSI_GREEN + "build_tag with value as: " + build_tag + ANSI_NORMAL) // 正常输出
        sh("echo build tag is ${build_tag}") // 正常输出
        sh '''
            export NVM_DIR="$HOME/.nvm"
            [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
            [ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
            snyk container test ${hub_org}/player:${build_tag} --json | snyk-to-html -d -o snyk_results.html
        '''
        sh("echo build tag is ${build_tag}") // 正常输出
    }
}

build_tag定义代码

node('build-slave') {
    try {
        String ANSI_GREEN = "\u001B[32m"
        ... // 其他颜色变量

        ansiColor('xterm') {
            timestamps {
                stage('Checkout') {
                    if (!env.hub_org) {
                        println(ANSI_BOLD + ANSI_RED + "Uh Oh! Please set a Jenkins environment variable named hub_org with value as registery/sunbidrded" + ANSI_NORMAL)
                        error 'Please resolve the errors and rerun..'
                    } else {
                        println(ANSI_BOLD + ANSI_GREEN + "Found environment variable named hub_org with value as: " + hub_org + ANSI_NORMAL)
                    }
                }
                checkout scm
                commit_hash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
                build_tag = sh(script: "echo " + params.github_release_tag.split('/')[-1] + "_" + commit_hash + "_" + env.BUILD_NUMBER, returnStdout: true).trim()
                echo "build_tag: " + build_tag

                stage('Customize dependencies') {
                    ...
                }
                stage('Snyk Setup') {
                    ...
                }
...

控制台输出片段

22:54:42  + snyk container test registery/sunbidrded/player: --json
22:54:42  + snyk-to-html -d -o snyk_results.html
22:54:47  Vulnerability snapshot saved at snyk_results.html
[Pipeline] sh
22:54:47  + echo build tag is container_scanning_ad2aecee29_23
22:54:47  build tag is container_scanning_ad2aecee29_23

可以看到${build_tag}在shell脚本中被解析为空,容器名称后仅保留冒号。


问题原因

Groovy中,三个单引号(''')包裹的是多行原生字符串,不会对其中的${变量}进行插值解析。因此脚本里的${hub_org}和${build_tag}会被当作shell自身的变量处理,而shell环境中未定义这些变量,最终输出为空。

而之前的sh("echo build tag is ${build_tag}")使用双引号包裹,Groovy会先完成变量插值,再将完整字符串传递给shell执行,所以能正常输出。


解决方法

方法1:改用双引号包裹脚本,转义内部双引号

将shell脚本用三个双引号(""")包裹,同时对脚本内部的双引号用\转义,确保Groovy先完成变量插值,再传递给shell。注意shell自身的变量(如$HOME)要加\避免被Groovy误插值:

sh """
    export NVM_DIR=\"\$HOME/.nvm\"
    [ -s \"\$NVM_DIR/nvm.sh\" ] && . \"\$NVM_DIR/nvm.sh\"
    [ -s \"\$NVM_DIR/bash_completion\" ] && . \"\$NVM_DIR/bash_completion\"
    snyk container test ${hub_org}/player:${build_tag} --json | snyk-to-html -d -o snyk_results.html
"""

方法2:注入Groovy变量到shell环境变量

通过sh命令的environment参数将Groovy变量注入shell环境,脚本中直接使用shell环境变量(推荐,避免转义麻烦):

sh(script: '''
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
    [ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
    snyk container test $HUB_ORG/player:$BUILD_TAG --json | snyk-to-html -d -o snyk_results.html
''', environment: [
    HUB_ORG: hub_org,
    BUILD_TAG: build_tag
])

方法3:字符串拼接单引号脚本

将需要插值的变量部分用双引号包裹,与单引号脚本拼接,Groovy会自动解析双引号内的变量:

sh '''
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
    [ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
    snyk container test ''' + "${hub_org}/player:${build_tag}" + ''' --json | snyk-to-html -d -o snyk_results.html
'''

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:05:27