Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkinsfile ${steps.env.BUILD_NUMBER}: bad substitution

I am trying to print a variable in Jenkins. But I am getting an error saying "bad substitution". I am using Jenkinsfile to achieve that. This is what I am doing.

static def printbn() {
    sh '''
            #!/usr/bin/env bash

            echo \"${env.BUILD_NUMBER}\"
    '''
}

pipeline {
    agent any
        stages {
            stage('Print Build Number') {
                steps {
                    printbn()
                }
            }
        }
}

Error that I am getting

/var/lib/jenkins/workspace/groovymethod@tmp/durable-7d9ef0b0/script.sh: line 4: ${steps.env.BUILD_NUMBER}: bad substitution

NOTE: I am using Jenkins version Jenkins ver. 2.163

like image 313
user3847894 Avatar asked Feb 17 '19 14:02

user3847894


People also ask

What is bad substitution in shell script?

It's a typographical fault that happens when you run your Shell script, and it can happen for a variety of reasons. The wrong use of instruction substitution and erroneous characters appended to the program are two major reasons for this.

What is SH in Jenkins pipeline?

On Linux, BSD, and Mac OS (Unix-like) systems, the sh step is used to execute a shell command in a Pipeline. Jenkinsfile (Declarative Pipeline) pipeline { agent any stages { stage('Build') { steps { sh 'echo "Hello World"' sh ''' echo "Multiline shell steps works too" ls -lah ''' } } } }


Video Answer


1 Answers

In Shell, variable name is not allow use ., that's why you get following error: bad substitution

In Groovy, there are 4 ways to represent a string:

  1. single quote: ' a string '
  2. tripe single quote: ''' a string '''
  3. double quote: " a string "
  4. tripe double quote: """ a string """

And Groovy only execute string interpolation on double and triple double quote string.

For example:

def name = 'Tom'

print "Hello ${name}"
print """Hello ${name}"""  
// do interpolation before print, thus get Hello Tom printed out

print 'Hello ${name}' 
print '''Hello ${name}'''
//no interpolation thus, print Hello ${name} out directly.

BUILD_NUMBER is Jenkins job's build-in environment variable. You can directly access it in shell/bat.

static def printbn() {
    sh '''
    #!/usr/bin/env bash

    echo ${BUILD_NUMBER} 
    // directly access any Jenkins build-in environment variable,
    // no need to use pattern `env.xxxx` which only works in groovy not in shell/bat
    '''
}

If you want use env.xxxx pattern, you can archive that via groovy string interpolation.

static def printbn() {

    // use pipeline step: echo
    echo "${env.BUILD_NUMBER}" // env.BUILD_NUMBER is groovy variable 

    // or use pipeline step: sh
    sh """#!/usr/bin/env bash
      echo ${env.BUILD_NUMBER} 
    """
    // will do interpolation firstly, to replace ${env.BUILD_NUMBER} with real value
    // then execute the whole shell script.
}
like image 67
yong Avatar answered Oct 12 '22 08:10

yong