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

Jenkins:在Shell脚本与Stage间传递变量的技术问题

当然可行!问题出在Shell与Groovy变量的隔离以及赋值方式

你的需求完全可以实现,核心问题是你混淆了Jenkins Groovy变量和Shell子进程变量的作用域——Shell步骤是在独立的子进程中运行的,里面的SERVER变量无法直接影响Groovy层面的SERVER变量。另外你的Shell赋值语法也有错误(赋值号两边不能有空格)。

问题拆解与修复步骤

  1. 捕获Shell脚本的输出到Groovy变量
    要让getServer.sh的输出传递回Groovy,需要用sh步骤的returnStdout: true参数,这样就能把Shell命令的标准输出作为Groovy的返回值。
  2. 修正Shell赋值语法
    Shell中变量赋值不能有空格,正确的捕获命令输出写法是SERVER=$(command),不过这里我们不需要在Shell里赋值,直接捕获输出即可。
  3. 在函数间传递变量
    可以让fetch_server函数返回获取到的服务器名,然后在Stage中把返回值赋值给Groovy的SERVER变量,再传递给provisioning函数。

修改后的完整代码

def SERVER

def fetch_server(token) {
    // 捕获getServer.sh的输出,trim去掉多余换行/空格
    return sh(
        script: """#!/bin/bash
        ${env.LOCAL_SCRIPT_PATH}/getServer.sh ${params.HOSTNAME} ${token}
        """,
        returnStdout: true
    ).trim()
}

def provisioning(server) {
    sh """#!/bin/bash
    ssh -o StrictHostKeyChecking=no username@${server} 'bash -s' ${env.REMOTE_SCRIPT_PATH}/script.py
    """
}

pipeline {
    agent {
        label 'slave1'
    }
    environment {
        REMOTE_SCRIPT_PATH = '/usr/local/bin/scripts'
        LOCAL_SCRIPT_PATH = './jobs/scripts'
    }
    parameters {
        string(
            name: 'HOSTNAME',
            defaultValue: '---',
            description: 'Enter the hostname of server'
        )
    }
    stages {
        stage('Stage 1: Fetch Server') {
            steps {
                withCredentials([string(credentialsId: 'some_cred', variable: 'TOKEN')]) {
                    // 将fetch_server的返回值赋值给Groovy变量SERVER
                    script {
                        SERVER = fetch_server(TOKEN)
                        echo "Fetched server: ${SERVER}" // 可选:验证变量是否正确获取
                    }
                }
            }
        }
        stage('Stage 2: Provisioning') {
            steps {
                sshagent(credentials : ['username']) {
                    // 将SERVER变量传入provisioning函数
                    script {
                        provisioning(SERVER)
                    }
                }
            }
        }
    }
    post {
        always {
            cleanWs()
        }
    }
}

关键改动说明

  • fetch_server函数现在接收token参数,并通过sh(returnStdout: true)捕获脚本输出,用trim()清理多余空白(避免换行符导致SSH连接失败)。
  • 在Stage 1中,用script块包裹Groovy代码,将fetch_server的返回值赋值给全局的SERVER变量。
  • provisioning函数接收server参数,在Shell脚本中用${server}引用Groovy变量(注意Groovy变量在双引号字符串中会被解析)。

这样就能完美实现跨Stage的服务器名称传递啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 11:13:14