15

I cannot use environment variables set in previous blocks in access stage below.

pipeline{
agent any
stages{

      stage("set env variable"){

      steps{
           script{
             env.city = "Houston"
             }
          }
       } 
     }
     stage("access"){
     steps{
           sh """
              set brf = ${env.city}
              echo $brf

              """

         }

     }



  } 
  }

ERROR: groovy.lang.MissingPropertyException: No such property: brf for class: groovy.lang.Binding

What is an easier way to use jenkins declarative pipeline env variables ?

aristotll
  • 8,694
  • 6
  • 33
  • 53
Varunkumar Manohar
  • 887
  • 3
  • 11
  • 29

2 Answers2

39

I cannot use environment variables set in previous blocks in access stage below.

If you look closely at the error, you can see Jenkins is actually unable to access brf, not env.city.

The issue here is caused by the way Jenkins interprets $var inside sh block:

  • if you use "double quotes", $var in sh "... $var ..." will be interpreted as Jenkins variable;
  • if you use 'single quotes', $var in sh '... $var ...' will be interpreted as shell variable.

Since the sh code in your script is wrapped in "double quotes", $brf is considered to be a Jenkins variable, while there is no such variable defined, therefore the error occurs.

To use shell variable inside double-quoted block add \ before $:

sh "echo \$var"

works the same way as

sh 'echo $var'

This should fix your pipeline script:

pipeline{
    agent any
    stages{
        stage("set env variable"){
            steps{
                script{
                    env.city = "Houston"
                }
            }
        }
        stage("access"){
            steps{
                sh """
                    brf=${env.city}
                    echo \$brf
                """
            }
        }
    }
}

Output from the pipeline:

[test] Running shell script
+ brf=Houston
+ echo Houston
Houston
honorius
  • 481
  • 4
  • 7
  • If setting the variable in pipeline { environment { city="Houston .., both sh 'echo $city' and sh "echo $city" does work (Jenkins 2.150) – rhoerbe Dec 22 '18 at 08:57
  • The amazing explanation when mixing shell and groovy variables in Jenkins. This saved my day. thanks. – Santosh Kumar Arjunan Mar 13 '19 at 18:34
  • Can we access the variable brf outside of the shell if we use sh """ code """ ? I tried doing the same thing, it works as expected but only when I try to access that variable from different stage it could not find it, even if I set it as a env variable. Does anyone have any idea ? – Rob May 02 '19 at 21:49
  • thank you for this explanation on the quotes and double quotes... very very important – Miguel Costa Oct 28 '20 at 15:44
  • @honorius very simple question what about if we want to access the jenkins variable inside the single quote is there a way to also escape that? – Miguel Costa Oct 29 '20 at 11:55
  • @honorius God bless you for your answer – Ameba Brain Nov 19 '20 at 12:51
  • 1
    This is not how it's documented to work. Env variables set in one stage are not supposed to be accessible in subsequent stages. For example: "The directive can also be placed in the stages. Thus, that variable can be used only in steps of that particular stage." - https://www.lambdatest.com/blog/set-jenkins-pipeline-environment-variables-list/ This is extremely confusing. I confirmed in Jenkins 2.306 that the env set in one stage is _not_ in fact visible in later stages. – Triynko Sep 16 '21 at 18:21
-2

You should not have any problem to get the variables with this code:

 stage("access"){
     steps{
           sh "set brf = ${env.city}"
           echo '$brf'

      //or 
      sh "set brf = ${env.city} && echo $brf"

      }
 }

I think this is what you had asked but let me know if you have another doubt.

Guel135
  • 750
  • 7
  • 26
  • 2
    This appears to be `csh` (C shell) code rather than the more standard `sh` (Bourne shell / dash) or `bash`. I don't think first part of your example would work, since the`brf` variable is set in the shell process and Jenkins' built-in `echo` doesn't have access to that variable. – RichVel Jun 13 '18 at 05:18