Jenkins声明式Pipeline中shell嵌套变量替换报Bad substitution如何解决
问题解决方法
错误根因
- 你使用单三引号(''') 包裹shell脚本,Jenkins Pipeline中该类引号包裹的内容不会提前做Groovy上下文的变量插值,你从UI传入的
ARTIFACT_NAME属于Jenkins任务参数,存储在Groovy执行上下文,无法被直接传递到单引号包裹的shell环境中。 - Freestyle任务默认会自动把所有任务参数注入shell环境变量,所以你的
${${ARTIFACT_NAME}}写法可以生效,但Pipeline默认不做该注入,且${${ARTIFACT_NAME}}属于非POSIX兼容的shell间接变量写法,在多数Linux发行版默认的dash环境下会直接报Bad substitution错误。
修复方案
方案1:使用双三引号提前做Groovy变量插值(最符合你的预期)
把sh块的包裹符号换成双三引号""",只对需要Groovy提前替换的变量保留${变量名}写法,需要留给shell处理的$符号前加反斜杠转义即可,最终生成的执行命令和你预期完全一致:
pipeline{ agent { node{ label "${AGENT}" } } stages{ stage("Setting MultiJob Properties"){ steps{ sh """set +x export VERSION=\$(mvn -B -q -Dexec.executable=echo -Dexec.args=\${${ARTIFACT_NAME}} ) echo \$VERSION """ } } } }
以上代码中${ARTIFACT_NAME}会被Groovy提前替换为你传入的Sample_Artifact,\$转义后的符号会保留到shell执行阶段,最终运行的命令和你期望的完全一致。
方案2:保留单三引号,手动注入参数+使用兼容的间接变量写法
如果你需要保持单三引号的纯shell上下文写法,可以手动把Jenkins参数注入到shell环境,同时使用POSIX兼容的${!变量名}写法做间接引用:
pipeline{ agent { node{ label "${AGENT}" } } stages{ stage("Setting MultiJob Properties"){ steps{ sh '''set +x # 手动注入Jenkins参数到shell环境 export ARTIFACT_NAME=''' + ARTIFACT_NAME + ''' # 使用兼容的间接变量引用写法 export VERSION=$(mvn -B -q -Dexec.executable=echo -Dexec.args=${!ARTIFACT_NAME} ) echo $VERSION ''' } } } }
内容的提问来源于stack exchange,提问作者Daisy Dharshini
相关产品推荐
相关产品推荐

