28

I want to use a variable which I am using inside of my Jenkinsfile script, and then pass its value into a shell script execution (either as an environment variable or command line parameter).

But the following Jenkinsfile:

for (i in [ 'a', 'b', 'c' ]) {
    echo i
    sh 'echo "from shell i=$i"'
}

Gives the output:

a
from shell i=
b
from shell i=
c
from shell i=

Desired output is something like:

a
from shell i=a
b
from shell i=b
c
from shell i=c

Any idea how to pass the value of i to the shell scipt?

Edit: Based upon Matt's answer, I now use this solution:

for (i in [ 'a', 'b', 'c' ]) {
    echo i
    sh "i=${i}; " + 'echo "from shell i=$i"'
}

The advantage is, that I don't need to escape the " in the shell script.

Community
  • 1
  • 1
Joe
  • 3,090
  • 6
  • 37
  • 55

4 Answers4

36

Your code is using a literal string and therefore your Jenkins variable will not be interpolated inside the shell command. You need to use " to interpolate your variable inside your strings inside the sh. ' will just pass a literal string. So we need to make a few changes here.

The first is to change the ' to ":

for (i in [ 'a', 'b', 'c' ]) {
  echo i
  sh "echo "from shell i=$i""
}

However, now we need to escape the " on the inside:

for (i in [ 'a', 'b', 'c' ]) {
  echo i
  sh "echo \"from shell i=$i\""
}

Additionally, if a variable is being appended directly to a string like you are doing above ($i onto i=), we need to close it off with some curly braces:

for (i in [ 'a', 'b', 'c' ]) {
  echo i
  sh "echo \"from shell i=${i}\""
}

That will get you the behavior you desire.

Matthew Schuchard
  • 25,172
  • 3
  • 47
  • 67
  • THANK YOU! I wish I could upvote this 1000 times! The single quote vs. double quotes was my issue! – GCB613 Nov 01 '21 at 23:40
27

Extension to Matts answer: For multi-line sh scripts use

sh """
  echo ${paramName}
"""

instead of

sh '''
  echo ${paramName}
'''
codester
  • 117
  • 2
  • 9
TouDick
  • 1,262
  • 12
  • 18
  • post { always { script { def body sh( script: ''' cat "/tmp/output.text" body=$( – Ashish Karpe Jan 06 '23 at 11:03
  • I am getting in email Sending Body null..... this means variable from sh scope is not outside it so how can I make this work ? – Ashish Karpe Jan 06 '23 at 11:04
  • Most probably the problem is in non escaped $ which is being resolved by groovy before value is given to script/shell. Try using body=\$( – TouDick Jan 07 '23 at 22:23
  • or alternatively use ' or ''' instead of "/""". Then the string will be given to shell as is without trying to resolve any values inside. – TouDick Jan 07 '23 at 22:26
0

try this:

for (i in [ 'a', 'b', 'c' ]) {
    echo i
    sh '''
    echo "from shell i=$i"
    '''
}
chenchuk
  • 5,324
  • 4
  • 34
  • 41
0

For multi-line, this should also work:

for (i in [ 'a', 'b', 'c' ]) {
    echo i
    sh '''
        VAR1="'''+i+'''"
        echo $VAR1
    '''
}
James Risner
  • 5,451
  • 11
  • 25
  • 47