Jenkins:在Shell脚本与Stage间传递变量的技术问题
当然可行!问题出在Shell与Groovy变量的隔离以及赋值方式
你的需求完全可以实现,核心问题是你混淆了Jenkins Groovy变量和Shell子进程变量的作用域——Shell步骤是在独立的子进程中运行的,里面的SERVER变量无法直接影响Groovy层面的SERVER变量。另外你的Shell赋值语法也有错误(赋值号两边不能有空格)。
问题拆解与修复步骤
- 捕获Shell脚本的输出到Groovy变量
要让getServer.sh的输出传递回Groovy,需要用sh步骤的returnStdout: true参数,这样就能把Shell命令的标准输出作为Groovy的返回值。 - 修正Shell赋值语法
Shell中变量赋值不能有空格,正确的捕获命令输出写法是SERVER=$(command),不过这里我们不需要在Shell里赋值,直接捕获输出即可。 - 在函数间传递变量
可以让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
相关产品推荐
相关产品推荐

