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

Jenkins Groovy脚本如何等待make_debug.sh执行完成并输出结果?

Jenkins流水线执行Shell脚本并捕获输出的问题解决

问题背景

原Jenkins声明式流水线脚本如下:

#!/usr/bin/env groovy

def deploymentPaths = '[]'

pipeline{
  agent {
    label 'jenkins-agent'
  }
  stages{
    stage('Build debug'){
        steps{
            sh './make_debug.sh'
        }
    }
  }
}

为等待脚本执行完成并捕获输出,修改后的脚本如下:

#!/usr/bin/env groovy

def deploymentPaths = '[]'

pipeline{
  agent {
    label 'jenkins-agent'
  }
  stages{
    stage('Build debug'){
        steps{
            def sout = new StringBuilder(), serr = new StringBuilder()
            def proc = './make_debug.sh'.execute()
            proc.consumeProcessOutput(sout, serr)
            proc.waitForOrKill(10000)
            println "out> $sout\nerr> $serr"
        }
    }
  }
}

运行后出现如下错误:

WorkflowScript: 13: Expected a step @ line 13, column 7.
            def sout = new StringBuilder(), serr = new StringBuilder()
         ^
WorkflowScript: 13: Expected a step @ line 13, column 39.
            def sout = new StringBuilder(), serr = new StringBuilder()
                                         ^
WorkflowScript: 14: Expected a step @ line 14, column 7.
            def proc = './make_debug.sh'.execute()
         ^
WorkflowScript: 15: Method calls on objects not allowed outside "script" blocks. @ line 15, column 13.
               proc.consumeProcessOutput(sout, serr)
               ^
WorkflowScript: 16: Method calls on objects not allowed outside "script" blocks. @ line 16, column 13.
               proc.waitForOrKill(1000)
               ^
WorkflowScript: 12: Missing required parameter: "delegate" @ line 12, column 5.
          step{
       ^
WorkflowScript: 15: Arguments to "error" must be explicitly named. @ line 15, column 13.
               proc.consumeProcessOutput(sout, serr)
               ^
WorkflowScript: 16: Expecting "class java.lang.String" but got "1000" of type class java.lang.Integer instead @ line 16, column 32.
               proc.waitForOrKill(1000)

错误原因分析

  1. 声明式流水线限制:声明式流水线的steps块内只能使用Jenkins官方提供的流水线步骤(如sh、echo),不能直接编写原生Groovy代码(变量定义、对象方法调用等),必须用script块包裹这类逻辑。
  2. 参数类型不匹配:waitForOrKill方法要求传入字符串类型的超时时间,而非整数,需要将数值转为字符串。

正确实现方案

方案一:用script块包裹Groovy代码

将Groovy逻辑放在script块中,同时修正waitForOrKill的参数类型:

#!/usr/bin/env groovy

def deploymentPaths = '[]'

pipeline{
  agent {
    label 'jenkins-agent'
  }
  stages{
    stage('Build debug'){
        steps{
            script {
                def sout = new StringBuilder(), serr = new StringBuilder()
                def proc = './make_debug.sh'.execute()
                proc.consumeProcessOutput(sout, serr)
                proc.waitForOrKill('10000') // 改为字符串类型的超时时间
                println "out> $sout\nerr> $serr"
            }
        }
    }
  }
}

方案二:使用Jenkins sh步骤内置参数(更简洁)

Jenkins的sh步骤支持returnStdout和returnStderr参数,可直接捕获输出,无需手动处理进程:

#!/usr/bin/env groovy

def deploymentPaths = '[]'

pipeline{
  agent {
    label 'jenkins-agent'
  }
  stages{
    stage('Build debug'){
        steps{
            script {
                // 一次执行同时捕获合并后的输出(标准输出+错误输出)
                def output = sh(script: './make_debug.sh 2>&1', returnStdout: true).trim()
                println "脚本输出:\n$output"

                // 若需分开捕获标准输出和错误输出,脚本会执行两次,需注意:
                // def stdout = sh(script: './make_debug.sh', returnStdout: true).trim()
                // def stderr = sh(script: './make_debug.sh', returnStderr: true).trim()
                // println "标准输出:\n$stdout"
                // println "错误输出:\n$stderr"
            }
        }
    }
  }
}

补充:设置超时时间

如果需要为脚本执行设置超时限制,可以用timeout步骤包裹sh操作:

steps{
    script {
        timeout(time: 10, unit: 'SECONDS') {
            def output = sh(script: './make_debug.sh 2>&1', returnStdout: true).trim()
            println "脚本输出:\n$output"
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:25:32