将变量传递给jenkins管道作业中的bash脚本

时间:2016-10-29 20:43:42

标签: linux bash shell jenkins parameters

我有一个Jenkins管道作业,我在其中使用名为setup.sh的bash脚本配置我的环境,如下所示:

#!/bin/bash
export ARCH=$1
echo "architecture = " ${ARCH}

在Jenkins管道脚本中,使用以下命令调用setup.sh脚本:

def lib_arch='linux-ubuntu-14.04-x86_64-gcc4.8.4'
sh ". /opt/setup.sh ${lib_arch}"

遗憾的是,似乎将 NO 变量传递给setup.sh脚本,并且echo $ {ARCH}返回一个空字符串! 我试着改为:     sh“source /opt/setup.sh $ {lib_arch}” 这也失败了“源未找到”消息。 我也尝试将脚本的第一行更改为

#!/bin/sh

但它没有帮助。那么如何在Jenkins管道脚本中将参数传递给我的bash脚本呢? 谢谢你的帮助。

更新: Bert Jan Schrijve在这篇帖子中提出了一个解决方法(见下文):

sh "bash -c \" source /opt/setup.sh ${lib_arch}\"" 

7 个答案:

答案 0 :(得分:2)

以下示例有效:

void updateApplicationVersionMaven(String version) {
    sh "mvn -B versions:set -DnewVersion=$version"
}

一个完整的管道脚本(在Jenkins 2.7.3上测试):

node {
    stage('test') {
        def testVar='foo'
        sh "echo $testVar"    
    }
}

编辑(评论后):啊,测试了一些,可以重现这个问题。这是因为您使用“./opt/setup.sh”获取脚本。这会影响shell环境,在这种情况下会破坏Jenkins变量注入。有趣。

EDIT2(评论后):我认为这是正在使用的默认shell的问题(由Jenkins或OS提供)。 我可以从评论中重现这个问题,并且能够通过明确地将bash用作shell来解决它:

def testVar='foo3'
sh "bash -c \". /var/jenkins_home/test.sh $testVar && echo \$ARCH\""

最后一个echo现在回应了testVar的内容,它作为参数传递给脚本,然后由脚本设置为环境变量。

答案 1 :(得分:1)

我用另一种方式解决了:

  1. 使用所需变量创建文件
  2. 在同一命令中运行source和命令本身
  3. 示例:

    sh 'echo -n HOST_IP= > host_ip.var'
    sh '/sbin/ip route|awk \'/default/ { print $3 }\' >> host_ip.var'
    sh 'source host_ip.var && echo your ip: $HOST_IP'
    

    文件以

    结尾
    REMOTE=172.16.0.1
    

    输出

    your ip: 172.16.0.1
    

    注意:最后一个sh命令使用单引号(')而非双(")非常重要,否则管道会尝试替换所述变量

答案 2 :(得分:1)

https://stackoverflow.com/a/55454037/6432452谢谢@Tony。这为我解决了!我尝试了一切!

对于需要第二个管道的状态码并由于使用sh时出现“错误替换”错误而被迫在Jenkins中使用bash的人。

mystring

您还必须将shebang与'''放在同一行

https://devops.stackexchange.com/questions/9942/prevent-pipelinestatus0-from-being-evaluated-in-jenkinsfile

答案 3 :(得分:0)

如果您使用带三撇号的多行shell脚本,则必须使用以下语法:

sh '''
 echo '''+varToPrint+'''
 other commands...
'''

(来自https://medium.com/devopslinks/a-hacky-hackers-guide-to-hacking-together-jenkins-scripted-pipelines-part-3-aca73bd33eaa

答案 4 :(得分:0)

使用带有env的returnStdout是来回传递val的另一种方法。示例显示了uuidgen的唯一ID被用作跨阶段的公共外部资源。

node {
    stage('stage 1') {
        env.UNIQUE = sh(returnStdout: true, script: 'uuidgen').trim()
        sh 'echo "started `date`" > /tmp/$UNIQUE'
    }
    stage('stage 2'){
        sh 'echo "done `date`" >> /tmp/$UNIQUE'
        println sh(returnStdout: true, script: 'cat /tmp/$UNIQUE').trim()
    }
}

这会将日期输出到一个唯一的文件,显示完成的时间。每次运行时,uuidgen都会生成一个不同的字符串。

+ echo 'done Tue Oct 22 10:12:20 CDT 2019'
[Pipeline] sh
+ cat /tmp/d7bdb6a5-badb-474d-95dd-cf831ea88a2a
[Pipeline] echo
started Tue Oct 22 10:12:20 CDT 2019
done Tue Oct 22 10:12:20 CDT 2019

答案 5 :(得分:0)

在我的情况下,我只需要将初始目录(工作区安装的地方)保存到 docker 代理中。因此,它可以稍后用作其他构建命令的输入。通常我更喜欢使用 bash 变量,但经过反复试验,我最终这样做了:

stage('Build') {
    agent {
        docker { ... }
    }
    steps {
        script {
            MYPWD = sh( script: 'pwd', returnStdout: true );
        }
        sh "echo $MYPWD"
    }
}

答案 6 :(得分:-1)

遇到同样的问题,发布的解决方案对我不起作用。使用环境变量可以达到目的:

env.someVar='someVal'
sh "echo  ${env.someVar}"