Search code examples
jenkinsjenkins-pipelinejenkins-groovy

Bad substitution when passing parameter to shell script in Jenkinsfile


In a Jenkinsfile I'm attempting to set an environment variable by setting the stdOut of a shell script. The script contains an AWS command that returns an InstanceID:

stage('Set InstanceID') {
         steps {
             script {
           env.IID = sh (script: 'scripts/get-node-id.sh "${params.ENVIRONMENT}" "${params.NODE}"', returnStdout: true).trim()
             }
          }
    }

No matter what I do or how many backslashes I use to escape the quotes, nothing works. I get a bad substitution error. I've also tried without double quotes.

If I hardcode in the shell script arguments, it runs fine.

How do I get this working if I want to use the parameter values here?


Solution

  • Groovy (the language of the Jenkinsfile) and Bash share the same substitution syntax. As you're using single quotes in your example code, the Groovy substitution does not work (see https://groovy-lang.org/syntax.html#_single_quoted_string). So Bash will try to do the substitution, but does not know these variables as they are Jenkins parameter values.

    So solve this you need to use double quotes for your script and escape the double quotes in it (or use singe quotes):

    stage('Set InstanceID') {
        steps {
            script {
                env.IID = sh (script: "scripts/get-node-id.sh \"${params.ENVIRONMENT}\" \"${params.NODE}\"", returnStdout: true).trim()
            }
        }
    }