繁体   English   中英

在詹金斯管道作业中将变量传递给 bash 脚本

[英]passing variable to bash script in a jenkins pipeline job

我有一个 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}"

不幸的是,似乎没有变量传递给 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}\"" 

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

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

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

下面的例子有效:

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 或由操作系统)的问题。 我可以从评论中重现这个问题,并且能够通过显式使用 bash 作为 shell 来解决它:

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

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

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

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

将 returnStdout 与 env 一起使用是另一种来回传递 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

我用另一种方式解决了:

  1. 创建一个包含所需变量的文件
  2. 在同一命令中运行source和命令本身

示例:

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命令使用单引号( ' ),不是双重( " ),否则管道试图取代所述可变

https://stackoverflow.com/a/55454037/6432452谢谢@Tony。 这对我有用! 我什么都试过了!

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

    def verify(name, config) {
script {
    sh '''
      #!/bin/bash
      docker-compose run --rm -e HOST='''+name+''' test rake -f test/Rakefile test_'''+config+''' | tee -a test-output-'''+config+'''.log; test "${PIPESTATUS[0]}" -eq 0
    '''
  }
}

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM