Jenkins Pipeline中Shell输出全局访问及条件终止执行问题排查
Jenkins Pipeline 问题解决方案
先解决 groovy.lang.MissingPropertyException 错误
你遇到的这个错误 No such property: $env for class: groovy.lang.Binding,本质是变量引用语法错误:
- 在Jenkins Pipeline里,直接引用环境变量时不用加
$前缀,比如不能写$env.BUILD_NUMBER,正确写法是env.BUILD_NUMBER - 只有在双引号包裹的字符串内部,才需要用
${}或$来插值,比如sh "当前构建号:${env.BUILD_NUMBER}" - 检查你的代码片段,把所有单独出现的
$env.xxx改成env.xxx就能解决这个错误
1. 将Shell输出定义为全局可访问变量
要让Shell命令的输出能在所有Stage里用,得在全局作用域定义变量,再通过sh的returnStdout: true捕获输出:
声明式流水线写法
pipeline { agent any // 全局环境变量,所有Stage可见 environment { GLOBAL_SHELL_RESULT = "" } stages { stage('捕获Shell输出') { steps { script { // 用returnStdout: true获取输出,trim()去掉多余换行 GLOBAL_SHELL_RESULT = sh(script: 'echo "测试全局变量"', returnStdout: true).trim() } } } stage('跨Stage使用变量') { steps { echo "全局变量的值:${GLOBAL_SHELL_RESULT}" } } } }
脚本式流水线写法
// 全局变量,在所有stage外定义 def globalOutput = "" node { stage('获取Shell输出') { globalOutput = sh(script: 'cat package.json | grep version', returnStdout: true).trim() } stage('使用全局变量') { echo "捕获到的版本信息:${globalOutput}" } }
注意事项:
- 必须加
returnStdout: true,否则sh步骤只会返回执行状态码,不是输出内容 - 一定要用
trim(),否则输出末尾的换行符会导致后续判断或输出出现问题 - 声明式流水线里,变量赋值必须放在
script块内,因为声明式语法不允许直接在steps里赋值
2. 根据Shell输出做条件判断并终止流水线
当retval为False时终止后续Stage,核心是捕获输出后做判断,用error()终止流水线,或者标记构建状态:
完整示例(声明式)
pipeline { agent any environment { retval = "" } stages { stage('获取retval值') { steps { script { // 替换成你的实际shell命令,返回True/False retval = sh(script: 'your-shell-command', returnStdout: true).trim() } } } stage('判断是否终止') { steps { script { if (retval == 'False') { // 标记构建为失败,然后终止执行 currentBuild.result = 'FAILURE' error("retval为False,流水线终止") } } } } stage('仅当retval为True时执行') { // 用when条件判断,避免失败后继续运行 when { expression { currentBuild.result != 'FAILURE' } } steps { echo "retval为True,继续执行后续步骤" } } } }
简化方式(利用Shell返回码)
如果你的Shell命令可以通过返回码表示结果(0=成功/True,非0=失败/False),可以直接用sh的默认行为:
stage('检查retval') { steps { // 命令返回非0时,Jenkins会自动终止流水线 sh 'your-shell-command-that-exits-1-when-false' } }
关键提醒:
- 注意
retval的大小写,'False'和'false'是两个不同的值,判断时要严格匹配 error()函数会立即终止流水线,并且把构建标记为失败- 后续Stage一定要加
when条件,否则即使前面失败了,可能还会继续执行
内容的提问来源于stack exchange,提问作者hari989
相关产品推荐
相关产品推荐

