Jenkins Pipeline执行kubectl获取Pod IP报bad substitution错误求助
问题根因
报错集中在「Get Slave Pods IP Addresses」阶段script块后的两行sh命令,存在两处明确语法错误:
- 第一处:
sh 'echo Slave IP Details : ${env.jenkinsSlaveNodes}'用单引号包裹sh脚本时,Jenkins不会提前解析${env.jenkinsSlaveNodes}这个Jenkins侧环境变量,而是直接把内容传给Linux Shell执行,Shell中没有env.jenkinsSlaveNodes这种格式的变量定义,因此触发bad substitution语法错误。 - 第二处:
sh '==================================== Finish searching JMeter [Slave] IP Addresses ===================================='该行缺少echo命令,Shell会把这串字符当做可执行命令去查找执行,也会触发报错。
另外还有一个隐藏的逻辑错误:你部署JMeter Slave时给Pod打的标签是app.kubernetes.io/name=jmeter-distributed-slave-${JOBNAME}-${BUILD_NUMBER},但后续获取Pod IP时筛选的标签是app.kubernetes.io/instance=distributed-jmeter-slave-${JOBNAME}-${BUILD_NUMBER},标签不匹配会导致你最终拿到的IP地址为空,后续执行JMeter分布式测试时会失败。
修复后的阶段代码
stage('Get Slave Pods IP Addresses') { steps { container ('kubehelm') { sh 'echo ==================================== Start searching JMeter [Slave] IP Addresses ====================================' script { // 筛选标签和部署时保持一致,增加trim()去掉返回结果末尾多余的换行符 env.jenkinsSlaveNodes = sh(returnStdout: true, script:'kubectl get pods -l app.kubernetes.io/name=jmeter-distributed-slave-${JOBNAME}-${BUILD_NUMBER} -n perf-platform -o jsonpath=\'{.items[*].status.podIP}\' | tr \' \' \',\'').trim() } // 用双引号包裹,Jenkins会先解析变量再传给Shell执行 sh "echo Slave IP Details : ${env.jenkinsSlaveNodes}" // 补全echo命令 sh 'echo ==================================== Finish searching JMeter [Slave] IP Addresses ====================================' } } }
补充规则说明
Jenkins Pipeline中sh命令的变量解析规则:
- 单引号
''包裹的脚本内容:Jenkins不做任何变量解析,直接传给Shell执行,适合使用Shell本身变量、不需要Jenkins提前注入参数的场景 - 双引号
""包裹的脚本内容:Jenkins会先把脚本内的Jenkins侧变量(如${env.xxx}、${BUILD_NUMBER}等)替换成实际值,再传给Shell执行,适合需要传递Jenkins侧变量到Shell的场景
内容的提问来源于stack exchange,提问作者Sahan Jayawardena
相关产品推荐
相关产品推荐

