Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkins Pipeline: exporting and reading environment variable inside bash script

I have a build pipeline that needs to extract a value from a bit of bash script and use that value elsewhere. I tried to store the result of my bash script in an environment variable like this:

#!/usr/bin/env groovy

pipeline {
    agent none

    stages {
        stage('Break Jenkins') {
            agent any
            steps {    
                sh """
                  ENV_VAR=\$(awk -F'-' '{print \$2 }' <<< \$(ls installer-*-ia32-win.zip))
                  echo $ENV_VAR
                """
            }
        }
    }
}

When the interpreter hits the echo $ENV_VAR line, Jenkins throws an exception:

groovy.lang.MissingPropertyException: No such property: ENV_VAR for class: groovy.lang.Binding

I've tried to tell the Jenkins interpreter that ENV_VAR isn't a Jenkinsfile environment variable by escaping the dollar sign prefix like this:

echo \$ENV_VAR

and like this

echo '$ENV_VAR'

neither works as expected. I think this is an issue with my being inside of a string block (the sh """ ... """) syntax, and also telling Jenkins not to try to get the value of ENV_VAR out of the envs collection.

Anyway, I'm not having much luck googling for the solution to this problem, because Jenkins' pipelines have their own notion of environment variables that seem to be separate from bash environment variables.

It looks like I can only set a Jenkinsfile environment variable inside of an environment block, which isn't helpful because I'm already inside of an sh block.

Put simply, is there a way to set and access the value of an environment variable from within an sh block?

like image 523
MusikPolice Avatar asked Feb 07 '18 21:02

MusikPolice


1 Answers

Double quotes used in sh command generates a problem in your case - GString tries to interpret $ENV_VAR but there is no such variable defined in current scope. Simple solution to this problem - use single quotes instead.

Also it is worth adding #!/bin/bash in the beginning of your script - otherwise you may face failing build with error like:

script.sh: line 3: syntax error: unexpected redirection

Below you can find modified pipeline script that worked well in my Jenkins sandbox:

#!/usr/bin/env groovy

pipeline {
    agent none

    stages {
        stage('Break Jenkins') {
            agent any
            steps {    
                sh '''#!/bin/bash
                  ENV_VAR=$(awk -F'-' '{print $2 }' <<< $(ls *))
                  echo $ENV_VAR
                '''
            }
        }
    }
}

Of course in my case I have simplified ls to $(ls *) because there are no files that match expression from your example. Hope it helps.

Btw, if you expect your bash script to return something you want to use in your pipeline, you have to execute sh in a following way:

sh(script: "your script", returnStdout: true)

Reference: https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script

like image 142
Szymon Stepniak Avatar answered Sep 22 '22 21:09

Szymon Stepniak