简体   繁体   中英

Executing Groovy command through Jenkins: "find: missing argument to `-exec'"

Im trying to copy the resulting war file from one build directory to another using Jenkins pipeline script(groovy). I have tested the find/exec/cp command on the system itself as the jenkins user, from the same workspace as the script runs and it works fine (direct copy paste from console out).

String buildNumber = env.BUILD_NUMBER

def sout = new StringBuffer()
def serr = new StringBuffer()

//Create package directory in jenkins job folder
def packageDir = "${env.JENKINS_HOME}/jobs/Package_Deploy_Pipeline/builds/${buildNumber}/package/"
def command = "mkdir ${packageDir}"
def proc = command.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(3000)
println "out> $sout err> $serr"

command = "find ${env.JENKINS_HOME}/jobs/myJob/builds/lastSuccessfulBuild/archive/build/libs/ -name *.war -exec cp {} ${packageDir} \\;"
println command
proc = command.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(3000)
println "out> $sout err> $serr"

The error seen in Console Output is:

[Pipeline] echo
out>  err> 
[Pipeline] echo
find /var/lib/jenkins/jobs/myJob/builds/lastSuccessfulBuild/archive/build/libs/ -name *.war -exec cp {} /var/lib/jenkins/jobs/Package_Deploy_Pipeline/builds/23/package/ \;
[Pipeline] echo
out>  err> find: missing argument to `-exec'

Edit: I have also tried "*.war" , '*.war' , \\; and ';'

带有声明式管道的Jenkins 只对我有用:

sh 'find . -ipath "*src/header.h" -exec rm {} ";"'

Groovy

The problem for the error you are experiencing might be related with \\; and the fact that you are escaping as for bash/sh command, when in fact you are not using bash/sh , but running find executable.

The same approach needs to be applied to -name parameter, where quoting should be dropped from search pattern.

Example:

command = "find src -name *.txt -exec cp {} dst/ ;"
println "[cmd] ${command}"
proc = command.execute()

def sout = new StringBuffer()
def serr = new StringBuffer()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "[cmd.out] ${sout}"
println "[cmd.err] ${serr}"

Jenkins

If you are running this code from Jenkins and Pipeline job, probably most convenient way would be to use built-in sh step.

sh: Shell Script

This step allows a Jenkins server or slave running on Linux or a Unix-like machine to execute a shell script. Params: script: String - the script to execute sh "find src -name '*.txt' -exec cp {} dst/ \\;"

More information on the Pipeline DSL can be found in the Pipeline tutorial .

Pure Groovy

And after all why not replace find with just Groovy code:

("src" as File).eachFileRecurse{
    if (it.name ==~ ".*\\.txt") {
        ...
    }
}

Isn't that more elegant?

I didn't resolve why the command was failing but i'm going to assume its groovys conversion to sh breaking when chaining commands. My solution was to break up the find and copy command.

location = "find ${env.JENKINS_HOME}/jobs/myJob/builds/lastSuccessfulBuild/archive/build/libs/ -name *.war".execute().text
command = "cp $location ${packageDir}myJob.war"
proc = command.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(3000)
println "out> $sout err> $serr"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM