I am trying to run the find command inside Jenkins (https://jenkins-ci.org) script console, which allows running groovy scripts from a web interface.
My code is:
ProcessBuilder pb = new ProcessBuilder();
pb.directory(new File("/var/lib/jenkins/jobs/myJob");
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
command = 'find . -name build.xml -exec echo \"{}\" \\;'
println(command)
pb.command(command.split(" "));
pb.start().waitFor();
The web UI will display the result of println:
find . -name build.xml -exec echo "{}" \;
While the jenkins log (/var/log/jenkins/jenkins.log) logs the following error:
find: missing argument to `-exec'
However, if I run that same command outputted in the web UI (find . -name build.xml -exec echo "{}" \;) through a shell I get no such error. 
In addition, if I replace the \; witih +, the command works!
So something is fishy with processBuilder and the \\; being passed as a command line argument
The problem for the error with \; is that you are mixing shell escaping/quoting with the plain passing of params of the exec functions.
Drop the \ before the ; and it works.  ; needs \ only in the shell, since it is used to separate commands there.  Same goes for quoting {} - when passing params to the exec*-style functions, no shell-style quoting/escaping is needed, since no shell interprets it (unless of course you run sh -c):
def command = 'find . -name build.xml -exec echo {} ;' // XXX
new ProcessBuilder()
    .directory(new File("/tmp"))
    .inheritIO()
    .command(command.split(" ")) // everything is just a list of strings
    .start()
And this is basically the same thing in groovy:
("/tmp" as File).eachFileRecurse{
    if (it.name=="build.xml") {
        println it
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With