6

I have a pipeline stage where I wait to get a certain string back from a sh script, and only when the strings match, continue to next stage, however, it doesn't work as expected:

node('master') {
    stage("wait for bash completion") {
        waitUntil {
            def output = sh returnStdout: true, script: 'cat /tmp/test.txt'
            output == "hello"
        }
    }
    stage("execute after bash completed") {
        echo "the file says hello!!!"
    }
}

The execution is something like that:

+ cat /tmp/test.txt
[Pipeline] }
Will try again after 0.25 sec
[Pipeline] {
[Pipeline] sh
[workspace] Running shell script
+ cat /tmp/test.txt
[Pipeline] }
Will try again after 0.3 sec
[Pipeline] {
[Pipeline] sh
[workspace] Running shell script
+ cat /tmp/test.txt
[Pipeline] }
Will try again after 0.36 sec
...
(so on and so forth)

What am I missing?

Moshe
  • 4,635
  • 6
  • 32
  • 57

2 Answers2

7

From waitUntil's help:

Runs its body repeatedly until it returns true. If it returns false, waits a while and tries again. --

Your execution output looks exactly like that it is waiting for output == "hello" to match. Maybe the content of file /tmp/test.txt is not exactly hello. You might have some whitespace in it, e.g. new line as the last character.

рüффп
  • 5,172
  • 34
  • 67
  • 113
Travenin
  • 1,511
  • 1
  • 13
  • 24
4

You probably need to add .trim() shell stdout to work, ie

def output = sh(returnStdout: true, script: 'cat /tmp/test.txt').trim()

Otherwise you end up with output showing a newline character at the end.

but probably, the better solution would be to use groovy script:

steps {
    sh "echo something > statusfile" // do something in the shell
    waitUntil(initialRecurrencePeriod: 15000) {
        script {
            def status = readFile(file: "statusfile")
            if ( status =~ "hello") {
                return true
            }else {
                println("no hello yet!")
                return false
            }
        }
    }
}
shaftdiesel
  • 416
  • 4
  • 7