Trying to pass a value from a shell variable to the next shell command (failed)

1,086 views
Skip to first unread message

JB

unread,
May 23, 2018, 8:48:52 AM5/23/18
to Jenkins Users
Hello All,

Anyone knows how to edit a variable from shell and recover the result across each next shells.

I'm trying to get the git tag version and to push the value into an env variable.
In next, I'd like to re use the value into the next cmd shell.

It doesn't work!

Anyone has an idea? I worked more than 2 days to trying to fix it.

        stage('Build image') {
            steps {
                sh 'TAG=$(git describe --candidate=1 --tags)'
                sh 'TAG=$(echo $TAG | cut -d\'-\' -f 1)'
                sh 'WEB_IMAGE_NAME=' + env['ACR_LOGINSERVER'] + '/my-project-1499882073260/test:' + env['TAG']
       
                sh 'sudo docker build -t ${WEB_IMAGE_NAME} -f WebApplication/WebApplication1/Dockerfile WebApplication/.'               
            }
        }

Ramanathan Muthaiah

unread,
May 23, 2018, 12:04:08 PM5/23/18
to Jenkins Users
        stage('Build image') { 
            steps {
                sh 'TAG=$(git describe --candidate=1 --tags)'
                sh 'TAG=$(echo $TAG | cut -d\'-\' -f 1)'
                sh 'WEB_IMAGE_NAME=' + env['ACR_LOGINSERVER'] + '/my-project-1499882073260/test:' + env['TAG']
       
                sh 'sudo docker build -t ${WEB_IMAGE_NAME} -f WebApplication/WebApplication1/Dockerfile WebApplication/.'               
            }
        }

How about like this ?

def tag = sh (returnStdout: true, script: "git describe --candidate=1 --tags").trim()
env.TAG = sh (returnStdout: true, script: "echo ${tag} | cut -d\'-\' -f 1").trim()

I haven't tested this code though, so, cannot guarantee it's success or failure, you may want to tweak and customize according to your needs. But, it's worth looking at / using the 'sh' step's return status and output.

Remember to use them inside 'script' block if you're using Declarative syntax.

/Ram

Slide

unread,
May 23, 2018, 12:42:39 PM5/23/18
to jenkins...@googlegroups.com
Another option would be to use triple quoted strings to run all the commands within the same shell execution. You'd have to deal with the env variables and possibly escaping $ as needed.

sh """TAG=\$(git describe...) | cut -d....
WEB_IMAGE_NAME=${ACR_LOGINSERVER}/.../\$(TAG)
sudo docker...."""
 

--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/44d030af-6af6-4f5a-815b-030e89fc5e3f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

JB

unread,
May 23, 2018, 1:01:27 PM5/23/18
to Jenkins Users
Like this?

        stage('Build image') {
            steps {
                sh """TAG=$(git describe --candidate=1 --tags)
                TAG=$(echo $TAG | cut -d\'-\' -f 1)
                WEB_IMAGE_NAME=$ACR_LOGINSERVER/my-project-1499882073260/test:$TAG
                sudo docker build -t $WEB_IMAGE_NAME -f WebApplication/WebApplication1/Dockerfile WebApplication/."""

Does not work. Maybe I did not written properly.

this is my result :

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 23: illegal string body character after dollar sign;
   solution: either escape a literal dollar sign "\$5" or bracket the value expression "${5}" @ line 23, column 17.

                   sh """TAG=$(git describe --candidate=1 --tags)
                   ^
1 error

Edward Bond

unread,
May 23, 2018, 1:11:15 PM5/23/18
to jenkins...@googlegroups.com
Don’t use sing quotes ‘, make sure you use “, that way the string can be interpolated.


I also use a global helper that grabs the output of `sh` functions.

def runAndReturn(script){
  toReturn = sh(script:script, returnStdout: true)
  toReturn = toReturn[0..-2]
  println toReturn
  toReturn
}

stage('Build image') { 
    steps {
        tagBefore = runAndReturn("git describe --candidate=1 --tags")
        tag = runAndReturn("echo ${tagBefore} | cut -d\'-\' -f 1")
        webImageName = "${env.ACR_LOGINSERVER}/my-project-1499882073260/test:${tag}"
        sh "sudo docker build -t ${webImageName} -f WebApplication/WebApplication1/Dockerfile WebApplication/."
    }
}

or something like:


        stage('Build image') { 
            steps {
                sh """
                export TAG=$(git describe --candidate=1 --tags)'
                export TAG=$(echo $TAG | cut -d\'-\' -f 1)'
                export WEB_IMAGE_NAME=$ACR_LOGINSERVER/my-project-1499882073260/test:$TAG
                sudo docker build -t $WEB_IMAGE_NAME -f WebApplication/WebApplication1/Dockerfile WebApplication/.
                """            
            }
        }

First example would allow you to go through and get access to strings to have more control over the strings. Second is an example of how you could use it to stay in bash.


--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.

JB

unread,
May 23, 2018, 1:12:47 PM5/23/18
to Jenkins Users
Hello,

if like this..

        stage('Build image') {
            steps {
                script {
                    def TAG = sh (returnStdout: true, script: "git describe --candidate=1 --tags").trim()
                    env.TAG = sh (returnStdout: true, script: "echo ${tag} | cut -d\'-\' -f 1").trim()
                }
              ......

groovy.lang.MissingPropertyException: No such property: tag for class: groovy.lang.Binding
 at groovy.lang.Binding.getVariable(Binding.java:63)
 at

JB

unread,
May 23, 2018, 1:20:38 PM5/23/18
to Jenkins Users
Hello Edward,

This is my script at all
I think I did a mistake...


pipeline {
    agent any
   
    stages {
        stage('Build project') {
            steps {
                git credentialsId: '*****', url: 'https://******'
                sh 'dotnet build WebApplication/WebApplication1/WebApplication1.csproj'

            }
        }
   
        stage('Build image') {
            steps {
                tagBefore = runAndReturn("git describe --candidate=1 --tags")
                tag = runAndReturn("echo ${tagBefore} | cut -d\'-\' -f 1")
                webImageName = "${env.ACR_LOGINSERVER}/my-project-1499882073260/test:${tag}"
                sh "sudo docker build -t ${webImageName} -f WebApplication/WebApplication1/Dockerfile WebApplication/."
            }
        }
    }
}

def runAndReturn(script){
    toReturn = sh(script:script, returnStdout: true)
    toReturn = toReturn[0..-2]
    println toReturn
    toReturn
}

Thanks to all people!

Started by user demo
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 14: Expected a step @ line 14, column 17.

                   tagBefore = runAndReturn("git describe --candidate=1 --tags")
                   ^
WorkflowScript: 15: Expected a step @ line 15, column 17.

                   tag = runAndReturn("echo ${tagBefore} | cut -d\'-\' -f 1")
                   ^
WorkflowScript: 16: Expected a step @ line 16, column 17.

                   webImageName = "${env.ACR_LOGINSERVER}/my-project-1499882073260/test:${tag}"
                   ^
3 errors
 at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
 at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
 (...)
 at hudson.model.ResourceController.execute(ResourceController.java:97)
 at hudson.model.Executor.run(Executor.java:405)
Finished: FAILURE

Edward Bond

unread,
May 23, 2018, 1:27:28 PM5/23/18
to jenkins...@googlegroups.com
JB,

Sorry, you are using the declarative syntax. I run my builds with a different pattern.

Something like this might work for you, 



def runAndReturn(script){
    toReturn = sh(script:script, returnStdout: true)
    toReturn = toReturn[0..-2]
    println toReturn
    toReturn
}


pipeline {
    agent any 
    
    stages {
        stage('Build project') { 
            steps {
                git credentialsId: '*****', url: 'https://******'
                sh 'dotnet build WebApplication/WebApplication1/WebApplication1.csproj'
            }
        }
    
        stage('Build image') { 
            steps {
              script {

JB

unread,
May 23, 2018, 1:41:52 PM5/23/18
to Jenkins Users
OK,

because I'm a beginner, wich pattern are you using?

Edward Bond

unread,
May 23, 2018, 1:48:24 PM5/23/18
to jenkins...@googlegroups.com
You can use that pattern, it’s arguably better than what I use.

However my builds can look like, the environment really depicts how you can execute things. I have a node labelled “default"

def runAndReturn(script){
    toReturn = sh(script:script, returnStdout: true)
    toReturn = toReturn[0..-2]
    println toReturn
    toReturn
}


node("default"){
  stage('shhhh'){
    x = runAndReturn("echo 134")
    println(x)
  }
}




This outputs:

[Pipeline] stage
[Pipeline] { (shhhh)
[Pipeline] sh
[test] Running shell script
+ echo 134
[Pipeline] echo
134
[Pipeline] echo
134
[Pipeline] }
[Pipeline] // stage



JB

unread,
May 23, 2018, 8:24:08 PM5/23/18
to Jenkins Users
I found, I need to put these commands in a script clause
thanks for you help!

Edward Bond

unread,
May 23, 2018, 8:25:06 PM5/23/18
to jenkins...@googlegroups.com
No problem, glad you figured it out.


Reply all
Reply to author
Forward
0 new messages