passing variable to bash script in a jenkins pipeline job
Solution 1
If you are using multiline shell script with triple apostrophe, you have to use this syntax:
sh '''
echo '''+varToPrint+'''
other commands...
'''
Solution 2
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):
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". This influences the shell environment, and in this case breaks the Jenkins variable injection. 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). I could reproduce the issue from the comments and was able to work around it by explicitly using bash as a 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.
Solution 3
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}"
Solution 4
Using the returnStdout with env is another way to pass val back and forth. Example shows a unique id from uuidgen is used as a common external resource across stages.
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.
+ 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
Solution 5
I've solved in another way:
- Create a file with the desired variables
- Run, in the same command, both a
source
and the command itself
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
NabilG
Updated on July 05, 2022Comments
-
NabilG almost 2 years
I have a Jenkins pipeline job in which I configure my environment with a bash script named setup.sh which looks like:
#!/bin/bash export ARCH=$1 echo "architecture = " ${ARCH}
In the Jenkins pipeline script, Icall the setup.sh script with:
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! I tried to instead do: sh "source /opt/setup.sh ${lib_arch}" and this fails as well with the "source not found" message. 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? thanks for your help.
Update: a workaround was sugggested by Bert Jan Schrijve in this thread (see below):
sh "bash -c \" source /opt/setup.sh ${lib_arch}\""