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

Jenkins执行远程Shell命令时如何捕获错误文本并推送至Telegram

Jenkinsfile 中 executeOnServer 函数错误信息优化方案

问题根源在于原实现只捕获了退出码异常,没有收集远程命令执行的真实错误输出(比如Docker守护进程的报错内容),导致Telegram推送的消息缺少关键详情。以下是修改后的实现:

修改后的函数代码

private def executeOnServer(String serverCredentialId, String command) {
    def stdout = ""
    def stderr = ""
    try {
        // 使用sshCommand直接捕获标准输出和错误输出(推荐方式)
        def cmdResult = sshCommand(
            credentialsId: serverCredentialId,
            command: command,
            returnStdout: true,
            returnStderr: true,
            timeout: 120 // 超时时间,单位秒
        )
        stdout = cmdResult.stdout.trim()
        stderr = cmdResult.stderr.trim()
        
        // 检查命令退出码,非0则主动抛出异常
        if (cmdResult.exitStatus != 0) {
            throw new Exception("命令执行退出码: ${cmdResult.exitStatus}")
        }
    } catch (Exception e) {
        // 整合完整错误信息
        def errorMsg = """⚠️ 远程命令执行失败
---
服务器凭据ID: ${serverCredentialId}
执行命令:
`${command}`
---
异常原因: ${e.getMessage()}
---
错误输出详情:
${stderr ?: stdout ?: '无输出内容'}"""
        
        // 推送至Telegram
        telegramSend(message: errorMsg)
        
        // 重新抛出异常,保持流水线错误状态
        throw e
    }
}

关键优化点

  • 改用sshCommand步骤:相比sshPublisher,sshCommand可以直接获取命令的标准输出(stdout)和错误输出(stderr),无需从构建日志中模糊截取,能精准拿到真实错误内容。
  • 主动检查退出码:即使命令执行过程中没抛出异常,只要退出码非0就主动触发异常,确保所有执行失败场景都能被捕获。
  • 整合完整错误上下文:把服务器信息、执行的命令、异常原因、真实错误输出全部整合到推送消息中,方便快速定位问题。
  • 保留流水线错误状态:重新抛出异常,避免掩盖错误,让Jenkins流水线能正确标记失败状态。

备选方案(若坚持用sshPublisher)

如果因为环境限制必须使用sshPublisher,可以通过截取构建日志的方式获取错误内容:

private def executeOnServer(String serverCredentialId, String command) {
    try {
        sshPublisher(publishers: [sshPublisherDesc(
            configName: serverCredentialId,
            transfers: [sshTransfer(execCommand: command, execTimeout: 120000)]
        )])
    } catch (Exception e) {
        // 截取构建日志最后50行作为错误详情(可根据需求调整行数)
        def logContent = currentBuild.rawBuild.getLog(50).join('\n')
        def errorMsg = """⚠️ 远程命令执行失败
服务器凭据ID: ${serverCredentialId}
执行命令: `${command}`
异常信息: ${e.getMessage()}
日志详情:
${logContent}"""
        
        telegramSend(message: errorMsg)
        throw e
    }
}

这种方式的缺点是日志可能包含其他无关内容,不如sshCommand精准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:50:04