简体   繁体   English

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

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

I have a Jenkins pipeline job in which I configure my environment with a bash script named setup.sh which looks like:我有一个 Jenkins 管道作业,我在其中使用名为 setup.sh 的 bash 脚本配置我的环境,如下所示:

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

In the Jenkins pipeline script, Icall the setup.sh script with:在 Jenkins 管道脚本中,我调用 setup.sh 脚本:

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

unfortunately it seems that NO variable is passed to the setup.sh script, and the echo ${ARCH} return an empty string!不幸的是,似乎没有变量传递给 setup.sh 脚本,并且 echo ${ARCH} 返回一个空字符串! I tried to instead do: sh "source /opt/setup.sh ${lib_arch}" and this fails as well with the "source not found" message.我尝试改为: sh "source /opt/setup.sh ${lib_arch}" 并且这也失败了,并显示了“未找到源”消息。 I also tried changing the first line of my script to我还尝试将脚本的第一行更改为

#!/bin/sh

but it does not help.但它没有帮助。 So how can I pass a parameter to my bash script in a Jenkins pipeline script?那么如何在 Jenkins 管道脚本中将参数传递给我的 bash 脚本呢? thanks for your help.感谢您的帮助。

Update: a workaround was sugggested by Bert Jan Schrijve in this thread (see below):更新:Bert Jan Schrijve 在此线程中建议了一种解决方法(见下文):

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

If you are using multiline shell script with triple apostrophe, you have to use this syntax:如果您使用带有三个撇号的多行 shell 脚本,则必须使用以下语法:

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

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

The example below works:下面的例子有效:

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

And a complete pipeline script (tested on Jenkins 2.7.3):以及一个完整的管道脚本(在 Jenkins 2.7.3 上测试):

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

EDIT (after comments): Ah, tested some more and could reproduce the issue.编辑(评论后):啊,测试了更多,可以重现这个问题。 It's because you're sourcing the script with ". /opt/setup.sh".这是因为您使用“./opt/setup.sh”获取脚本。 This influences the shell environment, and in this case breaks the Jenkins variable injection.这会影响 shell 环境,在这种情况下会破坏 Jenkins 变量注入。 Interesting.有趣。

EDIT2 (after comments): I believe this is an issue with the default shell that's being used (either by Jenkins or by the OS). EDIT2(评论后):我相信这是正在使用的默认 shell(由 Jenkins 或由操作系统)的问题。 I could reproduce the issue from the comments and was able to work around it by explicitly using bash as a shell:我可以从评论中重现这个问题,并且能够通过显式使用 bash 作为 shell 来解决它:

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

The last echo now echos the contents of testVar that was passed as an argument to the script and subsequently set by the script as an environment variable.最后一个 echo 现在回显 testVar 的内容,该内容作为参数传递给脚本,随后由脚本设置为环境变量。

Had the same problem and the posted solutions did not work for me.有同样的问题,发布的解决方案对我不起作用。 Using environment variables did the trick:使用环境变量可以解决问题:

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

Using the returnStdout with env is another way to pass val back and forth.将 returnStdout 与 env 一起使用是另一种来回传递 val 的方法。 Example shows a unique id from uuidgen is used as a common external resource across stages.示例显示来自 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()
    }
}

this will output a date to a unique file showing when it completed.这将输出一个日期到一个独特的文件,显示它何时完成。 uuidgen will produce a different string each time you run it. 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

I've solved in another way:我用另一种方式解决了:

  1. Create a file with the desired variables创建一个包含所需变量的文件
  2. Run, in the same command, both a source and the command itself在同一命令中运行source和命令本身

Example:示例:

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'

The file ends up with该文件以

REMOTE=172.16.0.1

The output is输出是

your ip: 172.16.0.1

Note: it is very important that the last sh command uses single quotes ( ' ), not double ( " ), otherwise the pipeline tries to replace said variable注:这是非常重要的是,最后sh命令使用单引号( ' ),不是双重( " ),否则管道试图取代所述可变

https://stackoverflow.com/a/55454037/6432452 THANK YOU @Tony. https://stackoverflow.com/a/55454037/6432452谢谢@Tony。 This worked out for me!这对我有用! I tried everything!我什么都试过了!

For people that need 2nd pipe's status code and are forced to use bash in Jenkins because of the "Bad Substitution" Error when using sh.对于需要第二个管道状态代码并且由于使用 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
    '''
  }
}

You also have to put shebang on the same line as '''您还必须将 shebang 与 ''' 放在同一行

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

In my case I just needed to save initial directory (where workspace gets mount) into docker agent.在我的情况下,我只需要将初始目录(工作区安装的位置)保存到 docker 代理中。 So it could be used later as an input to some other build command.因此,它可以稍后用作其他构建命令的输入。 Normally I'd prefer to use bash variable, but after trial and error I ended up doing this:通常我更喜欢使用 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