如何从Bash脚本获取变量传入Jenkins Pipeline的Groovy代码
问题:Jenkins流水线中从Shell脚本传递变量到Groovy阶段
需求:将Shell代码块中生成的ENV1_PERMIT、ENV1_TOKEN变量导出到后续Groovy阶段,供serviceHelper.admitterDeploy()方法调用。目前仅当这两个变量为硬编码值时,方法才能正常运行。
原流水线代码片段
def serviceHelper { node { docker.image(env.DOCKER_REGISTRY + "/drainage/si-base-se:latest").inside('--privileged') { withEnv(['HOME=.']) { stage('Build Test') { withCredentials([ string(credentialsId: 'NPM_PERMIT', variable: 'NPM_PERMIT'), string(credentialsId: 'AUTHORIZATION', variable: 'AUTHORIZATION') ]) { sh ''' rm -rf node_modules npm config set strict-ssl false npm config set registry ${NPM_REGISTRY} npm config set _auth ${NPM_PERMIT} npm config set always-auth true npx npm@6.xx.yy install ENV1_PERMIT=$(echo <code to get string from AUTHORIZATION> ) export ENV1_PERMIT ENV1_TOKEN=$(echo <code to get string from AUTHORIZATION> ) export ENV1_TOKEN npm run build ''' } } stage('Deploy-ENV1') { withCredentials([ cfCredentials ]) { serviceHelper.admitterDeploy(<redacted arguments>,${ENV1_TOKEN}, ${ENV1_PERMIT}) } } } } } }
背景
处理一个通过Groovy文件部署的遗留UI程序,该文件在Jenkins Pipeline中运行。流水线通过docker.image创建运行环境,包含多阶段任务:
Build Test阶段从Jenkins凭证系统获取AUTHORIZATION等变量,通过Shell脚本从AUTHORIZATION中提取3个环境(ENV1/ENV2/ENV3)对应的permit和token,共6个字符串。Deploy-ENV1阶段需要调用serviceHelper.admitterDeploy(),传入提取出的环境专属permit和token,但当前无法从Shell脚本传递这两个值到Groovy方法中。
现有方案分析
方案1:全局Groovy变量赋值
思路:在外部定义全局变量,将Shell命令的输出赋值给变量。
问题:写法错误,默认情况下sh步骤仅执行命令,不会返回输出;需指定returnStdout: true才能获取命令的标准输出,且调用语法不正确。
方案2:使用returnstdout获取输出
思路:利用Jenkins的sh步骤参数returnStdout,将命令输出以字符串形式返回。
问题:调用语法错误,returnStdout是sh步骤的参数,需以键值对形式传递,而非写在Shell脚本字符串内部。
方案3:Shell的export命令
思路:通过export导出Shell变量,供后续阶段使用。
问题:不可行。每个sh步骤都是独立的子进程,export的变量仅在当前Shell进程内有效,Groovy代码运行在独立的沙箱环境中,无法直接获取Shell子进程的环境变量。
正确解决方案
方案:拆分Shell逻辑,通过returnStdout提取变量
将变量提取逻辑与npm构建逻辑拆分,单独执行提取命令并通过returnStdout获取输出,赋值给Groovy变量(或Jenkins环境变量),供后续阶段使用。
修改后的代码片段:
def serviceHelper { node { docker.image(env.DOCKER_REGISTRY + "/drainage/si-base-se:latest").inside('--privileged') { withEnv(['HOME=.']) { stage('Build Test') { withCredentials([ string(credentialsId: 'NPM_PERMIT', variable: 'NPM_PERMIT'), string(credentialsId: 'AUTHORIZATION', variable: 'AUTHORIZATION') ]) { // 执行npm构建操作 sh ''' rm -rf node_modules npm config set strict-ssl false npm config set registry ${NPM_REGISTRY} npm config set _auth ${NPM_PERMIT} npm config set always-auth true npx npm@6.xx.yy install npm run build ''' // 提取ENV1_PERMIT,通过returnStdout获取输出并去除换行 def env1Permit = sh( script: "echo \$AUTHORIZATION | <你的提取命令>", returnStdout: true ).trim() // 提取ENV1_TOKEN def env1Token = sh( script: "echo \$AUTHORIZATION | <你的提取命令>", returnStdout: true ).trim() // 将变量存入Jenkins环境变量,供后续阶段访问 env.ENV1_PERMIT = env1Permit env.ENV1_TOKEN = env1Token } } stage('Deploy-ENV1') { withCredentials([cfCredentials]) { // 从环境变量中获取值,传入方法 serviceHelper.admitterDeploy(<redacted arguments>, env.ENV1_TOKEN, env.ENV1_PERMIT) } } } } } }
关键注意事项
sh步骤需通过returnStdout: true参数开启输出返回功能,默认不返回。- 使用
trim()去除输出结果中的换行符,避免传递无效字符。 - Shell脚本中引用Jenkins变量时,需用
\$转义(如\$AUTHORIZATION),防止Groovy提前解析变量。 - 若需跨节点/容器传递变量,可使用
stash/unstash机制;本场景下在同一个Docker容器内,直接使用Jenkins环境变量即可。
内容的提问来源于stack exchange,提问作者Rell
相关产品推荐
相关产品推荐

