154

Given a jenkins build pipeline, jenkins injects a variable env into the node{}. Variable env holds environment variables and values.

I want to print all env properties within the jenkins pipeline. However, I do no not know all env properties ahead of time.

For example, environment variable BRANCH_NAME can be printed with code

node {
    echo ${env.BRANCH_NAME}
    ...

But again, I don't know all variables ahead of time. I want code that handles that, something like

node {
    for(e in env){
        echo e + " is " + ${e}
    }
    ...

which would echo something like

 BRANCH_NAME is myBranch2
 CHANGE_ID is 44
 ...

I used Jenkins 2.1 for this example.

JamesThomasMoon
  • 6,169
  • 7
  • 37
  • 63
  • 1
    env is a map. Did you try normal iteration? like -- env.each{ println it } – Jayan May 07 '16 at 02:20
  • 3
    Looks like a duplicate of http://stackoverflow.com/questions/36836806/retrieve-all-properties-of-env-in-jenkinsfile – Krzysztof Krasoń May 07 '16 at 08:54
  • try `env.each { name, value -> println "Name: $name -> Value $value" }` – Renato May 07 '16 at 16:34
  • 3
    Afaik env just encapsulates the environment variables. I dont think you can loop through it. Try 'sh env' on linux/ 'bat set' on windows. – Dominik Gebhart May 07 '16 at 16:41
  • 3
    @Renato @Jayan per my comment below, `env.each { name, value -> println "Name: $name -> Value $value" }` prints `Name: org.jenkinsci.plugins.workflow.cps.EnvActionImpl@45c2d1ee -> Value null`. – JamesThomasMoon May 09 '16 at 20:49
  • 1
    @JamesThomasMoon1979 That's because Pipeline breaks Groovy closures. If you right it old-Java style (that is, `new ClassName() { ... }`), it should work. Or you run it on a method tagged `@NonCPS`, then closures will work inside that too. – Daniel C. Sobral Jul 31 '16 at 08:51
  • 2
    the 'env' object ist NOT a map, but some class object. i tried it out on a Jenkins pipeline script. calls like ".each()" will result in "Name: org.jenkinsci.plugins.workflow.cps.EnvActionImpl@633862d -> Value null" whilst calls like ".containsKey(...)" will result in "hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: org.jenkinsci.plugins.workflow.cps.EnvActionImpl.containsKey() is applicable for argument types: (java.lang.String) values: [...]" – Alexander Stohr Apr 14 '23 at 08:17

20 Answers20

157

According to Jenkins documentation for declarative pipeline:

sh 'printenv'

For Jenkins scripted pipeline:

echo sh(script: 'env|sort', returnStdout: true)

The above also sorts your env vars for convenience.

Wimateeka
  • 2,474
  • 2
  • 16
  • 32
  • 4
    `printenv` is just a shell command that prints the environment, nothing specific to Jenkins. Without arguments it is equivalent to `env` without arguments. I'm pretty sure `sh 'printenv | sort'` will work in DCL or scripted pipeline. – simon.watts May 21 '18 at 13:23
  • 2
    Tested and `sh 'printenv | sort'` does in fact work for a Jenkins declarative pipeline; fwiw `sh 'env | sort'` also works (Both tested on Jenkins ver. 2.46.1). I originally mentioned `sh 'printenv'` because it was referenced in official Jenkins documentation. – Wimateeka May 21 '18 at 14:35
  • 1
    If you lose the returnStdout:true then you don't need the echo; It's just printing what the shell script printed already. – Ed Randall Nov 15 '18 at 14:41
95

Another, more concise way:

node {
    echo sh(returnStdout: true, script: 'env')
    // ...
}

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

mjfroehlich
  • 1,217
  • 10
  • 4
41

The following works:

@NonCPS
def printParams() {
  env.getEnvironment().each { name, value -> println "Name: $name -> Value $value" }
}
printParams()

Note that it will most probably fail on first execution and require you approve various groovy methods to run in jenkins sandbox. This is done in "manage jenkins/in-process script approval"

The list I got included:

  • BUILD_DISPLAY_NAME
  • BUILD_ID
  • BUILD_NUMBER
  • BUILD_TAG
  • BUILD_URL
  • CLASSPATH
  • HUDSON_HOME
  • HUDSON_SERVER_COOKIE
  • HUDSON_URL
  • JENKINS_HOME
  • JENKINS_SERVER_COOKIE
  • JENKINS_URL
  • JOB_BASE_NAME
  • JOB_NAME
  • JOB_URL
Omri Spector
  • 2,431
  • 24
  • 22
  • 1
    This doesn't work: `java.lang.UnsupportedOperationException: each on a CPS-transformed closure is not yet supported` – bsky Feb 09 '17 at 15:11
  • 5
    Did you make sure to include the `@NonCPS`? – Joe C. Mar 10 '17 at 20:28
  • 1
    This is the best answer because it will work outside of a *node* block. Thanks so much for this. – Gi0rgi0s Sep 06 '19 at 15:17
  • 2
    Not a good solution, `env.getEnvironment()` is not whitelisted to be used in pipeline scripts: `org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction getEnvironment`. – haridsv Jul 09 '21 at 06:38
  • 1
    As written in the answer: Note that it will most probably fail on first execution and ***require you approve various groovy methods to run in jenkins sandbox.*** This is done in "manage jenkins/in-process script approval" – Omri Spector Jul 11 '21 at 05:35
  • This is a good solution, because not in all cases you have node{} notation. If you want to parse Jenkins parameters before initializing node from shared library, this solution will work, otherwise sh('env') will fail. But @NonCPS is not needed here. – Vladislav Kovalyov Aug 26 '22 at 14:48
15

You can accomplish the result using sh/bat step and readFile:

node {
    sh 'env > env.txt'
    readFile('env.txt').split("\r?\n").each {
        println it
    }
}

Unfortunately env.getEnvironment() returns very limited map of environment variables.

luka5z
  • 7,525
  • 6
  • 29
  • 52
  • 2
    `sh 'env > env.txt'` works well and includes environment variables created by the shell process. `env.getEnvironment()` shows only the Jenkins set environment variables which are a subset of that seen in `sh 'env'` technique. Also, it needs script security approval `method org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction getEnvironment`. The `env.each { name, value -> println "Name: $name -> Value $value" }` recommended by @Renato @Jayan only prints `Name: org.jenkinsci.plugins.workflow.cps.EnvActionImpl@45c2d1ee -> Value null`. – JamesThomasMoon May 09 '16 at 21:49
  • Nice!!! Being able to print all env vars helped me discover that Jenkins 2 sets a JOB_BASE_NAME var contains the job name sans the folder it lives in. – Bill Agee Jun 12 '16 at 06:36
  • a version that works on windows would be awesome as well :) – Bas Hamer Jun 29 '16 at 19:54
  • @Bas Hamer for a windows version try to replace "sh" by "bat" – Sebastien Jul 20 '16 at 15:52
  • 2
    Gives me an error java.lang.UnsupportedOperationException: Calling public static java.lang.Object org.codehaus.groovy.runtime.DefaultGroovyMethods.each(java.lang.Object,groovy.lang.Closure) on a CPS-transformed closure is not yet supported (JENKINS-26481); encapsulate in a @NonCPS method, or use Java-style loops – Ben Mathews Dec 21 '16 at 18:56
  • There are a few other options over here that are a bit more concise, also I would note what types of Jenkins pipelines this works for, as it makes a big difference. – Wimateeka Oct 03 '17 at 21:01
15

Why all this complicatedness?

sh 'env'

does what you need (under *nix)

Andrey Regentov
  • 3,687
  • 4
  • 34
  • 40
  • 2
    This requires a node block to execute. For my use-case I need to process what environment the node will have then spin a node up based on certain criteria. – Bill Warner Sep 23 '19 at 17:15
14

Cross-platform way of listing all environment variables:

if (isUnix()) {
    sh env
}
else {
    bat set
}
Terry
  • 14,099
  • 9
  • 56
  • 84
11

Here's a quick script you can add as a pipeline job to list all environment variables:

node {
    echo(env.getEnvironment().collect({environmentVariable ->  "${environmentVariable.key} = ${environmentVariable.value}"}).join("\n"))
    echo(System.getenv().collect({environmentVariable ->  "${environmentVariable.key} = ${environmentVariable.value}"}).join("\n"))
}

This will list both system and Jenkins variables.

Daniel
  • 8,655
  • 5
  • 60
  • 87
9

The pure Groovy solutions that read the global env variable don't print all environment variables (e. g. they are missing variables from the environment block, from withEnv context and most of the machine-specific variables from the OS). Using shell steps it is possible to get a more complete set, but that requires a node context, which is not always wanted.

Here is a solution that uses the getContext step to retrieve and print the complete set of environment variables, including pipeline parameters, for the current context.

Caveat: Doesn't work in Groovy sandbox. You can use it from a trusted shared library though.

def envAll = getContext( hudson.EnvVars )
echo envAll.collect{ k, v -> "$k = $v" }.join('\n')
zett42
  • 25,437
  • 3
  • 35
  • 72
8

I use Blue Ocean plugin and did not like each environment entry getting its own block. I want one block with all the lines.

Prints poorly:

sh 'echo `env`'

Prints poorly:

sh 'env > env.txt'
for (String i : readFile('env.txt').split("\r?\n")) {
    println i
}

Prints well:

sh 'env > env.txt'
sh 'cat env.txt'

Prints well: (as mentioned by @mjfroehlich)

echo sh(script: 'env', returnStdout: true)
Jon Lauridsen
  • 2,521
  • 5
  • 31
  • 38
6

Show all variable in Windows system and Unix system is different, you can define a function to call it every time.

def showSystemVariables(){    
   if(isUnix()){
     sh 'env'
   } else {
     bat 'set'
   }
}

I will call this function first to show all variables in all pipline script

stage('1. Show all variables'){
     steps {
         script{            
              showSystemVariables()
         }
     }
} 
Assault72
  • 79
  • 1
  • 3
6

The easiest and quickest way is to use following url to print all environment variables

http://localhost:8080/env-vars.html/

Muhammad Maroof
  • 141
  • 1
  • 3
  • 9
3

The answers above, are now antiquated due to new pipeline syntax. Below prints out the environment variables.

script {
        sh 'env > env.txt'
        String[] envs = readFile('env.txt').split("\r?\n")

        for(String vars: envs){
            println(vars)
        }
    }
Eddie
  • 1,081
  • 2
  • 12
  • 28
3

ref: https://www.jenkins.io/doc/pipeline/tour/environment/

node {
    sh 'printenv'
}
ROY
  • 8,800
  • 1
  • 17
  • 13
3

Includes both system and build environment vars:

sh script: "printenv", label: 'print environment variables'
3

You can use sh 'printenv'

 stage('1') {
    sh "printenv" 
 }
2

if you really want to loop over the env list just do:

def envs = sh(returnStdout: true, script: 'env').split('\n')
envs.each { name  ->
    println "Name: $name"
}
datashaman
  • 8,301
  • 3
  • 22
  • 29
dsaydon
  • 4,421
  • 6
  • 48
  • 52
2

I found this is the most easiest way:

pipeline {
    agent {
        node {
            label 'master'
        }
    }   
    stages {
        stage('hello world') {
            steps {
                sh 'env'
            }
        }
    }
}
Prosenjit Sen
  • 326
  • 4
  • 7
2

You can get all variables from your jenkins instance. Just visit:

  • ${jenkins_host}/env-vars.html
  • ${jenkins_host}/pipeline-syntax/globals
Dmitriy Tarasevich
  • 1,082
  • 5
  • 6
1

I suppose that you needed that in form of a script, but if someone else just want to have a look through the Jenkins GUI, that list can be found by selecting the "Environment Variables" section in contextual left menu of every build Select project => Select build => Environment Variables

enter image description here

Community
  • 1
  • 1
claudod
  • 815
  • 8
  • 8
0

another way to get exactly the output mentioned in the question:

envtext= "printenv".execute().text
envtext.split('\n').each
{   envvar=it.split("=")
    println envvar[0]+" is "+envvar[1]
}

This can easily be extended to build a map with a subset of env vars matching a criteria:

envdict=[:]
envtext= "printenv".execute().text
envtext.split('\n').each
{   envvar=it.split("=")
    if (envvar[0].startsWith("GERRIT_"))
        envdict.put(envvar[0],envvar[1])
}    
envdict.each{println it.key+" is "+it.value}
Roman
  • 707
  • 8
  • 16