Jenkinsfile中Groovy语法疑问:三引号变量展开差异解析
Jenkinsfile中三引号脚本的输出差异解析
问题重现
环境变量定义
environment { BUILD_DIR = "${WORKSPACE}/build" }
Stage代码
stage('Stage1') { steps { sh label: 'Stage1 ...', script: """ echo ${BUILD_DIR} echo '${BUILD_DIR}' echo "${BUILD_DIR}" """ } } stage('Stage2') { steps { sh label: 'Stage2 ...', script: ''' echo ${BUILD_DIR} echo '${BUILD_DIR}' echo "${BUILD_DIR}" ''' } }
控制台输出
+ echo /home/builder/workspace/build /home/builder/workspace/build + echo /home/builder/workspace/build /home/builder/workspace/build + echo /home/builder/workspace/build /home/builder/workspace/build + echo /home/builder/workspace/build /home/builder/workspace/build + echo ${BUILD_DIR} ${BUILD_DIR} + echo /home/builder/workspace/build /home/builder/workspace/build
疑问解析
1. 为何两种情况下'${BUILD_DIR}'和"${BUILD_DIR}"的引号都被忽略?
这是Shell的解析逻辑导致的:
- 当Groovy把处理后的脚本传给Shell执行时,
echo 'xxx'或echo "xxx"中的单/双引号是Shell用来界定字符串边界的语法符号,不属于输出内容。Shell会自动解析引号,只输出引号包裹的内部文本,所以你看不到引号。
结合两个Stage的具体流程:
- Stage1(三双引号):Groovy会先对三双引号内的内容做变量插值,把
${BUILD_DIR}替换成实际路径,最终传给Shell的脚本是:
Shell执行时,后两行的引号被解析丢弃,只输出路径。echo /home/builder/workspace/build echo '/home/builder/workspace/build' echo "/home/builder/workspace/build" - Stage2(三单引号):Groovy不做变量插值,直接把原始内容传给Shell,脚本为:
Shell执行时,第二行的单引号阻止变量展开,输出echo ${BUILD_DIR} echo '${BUILD_DIR}' echo "${BUILD_DIR}"${BUILD_DIR};第三行的双引号允许Shell展开Jenkins环境变量BUILD_DIR,输出路径,引号同样被解析丢弃。
2. 为何三单引号场景下第二行的变量未被展开?
这是Groovy字符串插值规则和Shell变量展开规则共同作用的结果:
- Groovy的三单引号(
''' ''')是原始字符串,不会解析内部的${变量}语法,会原封不动把字符串传给Shell。 - 传给Shell的第二行是
echo '${BUILD_DIR}',Shell中单引号包裹的内容会被视为纯文本,不会展开任何变量,因此直接输出${BUILD_DIR}。
对比其他行:
- Stage2第一行
echo ${BUILD_DIR}:Groovy不插值,传给Shell后,Shell会直接展开Jenkins环境变量BUILD_DIR,输出路径。 - Stage2第三行
echo "${BUILD_DIR}":Groovy不插值,传给Shell后,Shell会展开双引号内的环境变量BUILD_DIR,输出路径。
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

