I have a groovy script as my Jenkins pipeline script, which looks something like
node(“nodeName”) {
. . . (some groovy code)
sh “”"
…
< This section of the shell script calculates the value of the variable varName, example being BUILD_NUMBER >
…
echo “${env.BUILD_ID}” # This prints expected output. Example : 51
export varName=“env.BUILD_NUMBER”
echo “${”$varName"}" # This prints the output as env.BUILD_NUMBER and not 51
“”"
…
}
In the above example, I had hard coded value of varName as env.BUILD_NUMBER. In my actual script, value of varName will be calculated during execution.
In bash script, this result can be achieved as follows:
#!/bin/bash
variable_1=“abc”
variable_2=variable_1
echo “${!variable_2}”
Exclamation mark (!) doesn’t work in shell script inside Jenkins pipeline
Can someone please explain, how to address my requirement ?
The env. portion is just useful inside of the groovy part of the pipeline. Everything in env is exported as an actual environment variable in the shell script.
If your shell script is wrapped in double quotes, then ${env.BUILD_ID} is being replaced by groovy and not the shell. Can you share your pipeline (redacted)? It would help understand your context better.
Thank you for replies and sorry for the delay in answering your questions
I solved my requirement through some other means and this thread can be closed
As @halkeye says, there is indeed a code smell. I would in fact suggest that using the sh step with Groovy strings interpolation (i.e. strings with double quotes) is generally a code smell. See the Injection via Interpolation section in the manual, which can be particularly dangerous for shell scripts.
The original question can be more or less solved directly solved by using an immutable string (single quotes). The workaround against Injection via Interpolation is to pass variable via the environment, but this is already the case here.
You can achieve all this variable substitution in a safer way directly in Bash:
script {
env.BUILD_ID = "1234"
env.BUILD_NUMBER = "5678"
}
sh '''#!/bin/bash
# The double-quotes here belong to the shell script,
# nothing to do with the Groovy string.
echo "$BUILD_ID"
varName="BUILD_NUMBER"
# Bash will expand this as echo "$BUILD_NUMBER", which will use the environment
# variable defined earlier, inside this shell script or passed to env in the groovy
# script
echo "${!varName}"
'''
Note: this way of expanding variables is specific to Bash and might require a different syntax with other shells (hence the #!/bin/bash at the start). If needed, you can check the shell running sh steps by default using sh 'readlink /proc/$$/exe'.