Why is Jenkins pipeline returning -@tmp/durable-56090643/script.sh 4: FSUM7728 bad ${} modifier for shell command?

Viewed 2306

I have this stage in my Jenkins pipeline that runs a command and stores the output in a variable. I'm trying to get the id number from the stored string but getting the error bad ${} modifier. Should have printed 00062100. It works correctly in the console.

  stage('test') {
   agent {node 'test'}
    steps{
        sh "string=$(onetstat -a -P 1111)"
        sh "echo ${string:6:8}"
    }
  }

output from the command("BUILD 00062100 Listen")

**Update:**    
stage('server2') {
   agent {node 'test'}
    steps{
            sh '''
                var="$(onetstat -a -P 1111)"
                echo ${var:6:8}
            '''
    }
  }

 **log of the run**
  [Pipeline] sh
    + + onetstat -a -P 1111 
    + 1<TMP> /tmp/shGgcEdAGgA 
 var=
 BUILDER8 00069B50 Listen  
 Local Socket:   127.0.0.1..1111                                     
 Foreign Socket: 0.0.0.0..0                                           
 /Build@tmp/durable-a93a2921/script.sh 3: FSUM7728 bad ${} modifier
2 Answers

There are two misunderstandings in your example. When you use double quotes in the Jenkinsfile, you construct a Groovy String that substitutes variables (defined using $ sign) with associated values (or expressions.)

Another misunderstanding is creating a bash variable in one sh step and accessing it in another sh step. It won't work that way. Each sh step runs in its own shell process, and any local variable created in one shell cannot be accessed in another.

You can solve both issues. Firstly, you need to replace double quotes with single quotes in sh step. Secondly, you need to define shell script in a single sh step. You can use Groovy multiline string for that (triple quotes.) Consider the following example:

pipeline {
    agent any

    stages {
        stage("Test") {
            steps {
                // Below code prints nothing
                sh 'something="BUILD 00062100 Listen"'
                sh 'echo ${something:6:8}'

                // Below code prints 00062100
                sh '''
                    something="BUILD 00062100 Listen"
                    echo ${something:6:8}
                '''
            }
        }
    }
}

Output:

[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] sh
+ something='BUILD 00062100 Listen'
[Pipeline] sh
+ echo

[Pipeline] sh
+ something='BUILD 00062100 Listen'
+ echo 00062100
00062100
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Used this solution to get the id from the command output

 var=$(onetstat -a -P 1111) 
 var=$(echo $var | cut -b 6-10) 
Related