"find: missing argument to `-exec'" 运行 在 Java 进程构建器中

"find: missing argument to `-exec'" running in a Java process builder

我正在尝试 运行 Jenkins (https://jenkins-ci.org) 脚本控制台中的 find 命令,它允许从 Web 界面 运行ning groovy 脚本。

我的代码是:

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();

网页UI会显示println的结果:

find . -name build.xml -exec echo "{}" \;

虽然 jenkins 日志 (/var/log/jenkins/jenkins.log) 记录了以下错误:

find: missing argument to `-exec'

但是,如果我 运行 通过 shell 在 Web UI (find . -name build.xml -exec echo "{}" \;) 中输出相同的命令,我不会收到这样的错误。

此外,如果我将 \; 替换为 +,该命令有效!

所以 processBuilder 和作为命令行参数传递的 \; 有点可疑

你不能把上面的都换成:

String output = ['bash', '-c', 'find . -name "*.xml" -exec echo "{}" \;']
    .execute(null, new File('/tmp')).text

\; 的错误问题是您将 shell escaping/quoting 与 exec 函数的参数的简单传递混合在一起。

; 之前删除 \ 即可。 ; 在 shell 中只需要 \ ,因为它用于分隔那里的命令。引用 {} 也是如此——当将参数传递给 exec* 风格的函数时,不需要 shell 风格的 quoting/escaping,因为没有 shell 解释它(当然除非你 运行 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()

这在 groovy 中基本相同:

("/tmp" as File).eachFileRecurse{
    if (it.name=="build.xml") {
        println it
    }
}