[英]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...
'''
下面的例子有效:
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
我用另一种方式解决了:
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 与 ''' 放在同一行
在我的情况下,我只需要将初始目录(工作区安装的位置)保存到 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.