在 groovy 脚本中执行外部程序并捕获输出

Dav*_*enz 4 groovy

我需要编写一个常规脚本,即执行外部程序并将该程序的输出打印到控制台。

这是相关的代码片段:

def pmdCommand = "${scriptDir}/run.sh pmd -d ${filesToAnalyse}"

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

def process = pmdCommand.execute()
process.consumeProcessOutput(sout, serr)
process.waitFor()
if (process.exitValue() !=0 ) {
    System.err << serr.toString()
    System.exit(-1)
} 
else {
    System.out << sout.toString()
    System.exit(0)
}
Run Code Online (Sandbox Code Playgroud)

我在Java中做了类似的事情,但我无法将其转换为groovy。

StringBuffer output = new StringBuffer();
String s = null;

try {
    Process p = Runtime.getRuntime().exec(command);
    p.waitFor();

    BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
    BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));

    while ((s = stdInput.readLine()) != null) {
        System.out.println(s);
    }

    while ((s = stdError.readLine()) != null) {
        System.err.println(s);
    }

    System.exit(0);
}
catch (Exception e) {
    e.printStackTrace();
    System.exit(-1);
}
Run Code Online (Sandbox Code Playgroud)

更新:我似乎 waitFor() 永远不会返回并阻止执行

Emmanuel Rosa 提供的解决方案:

def pmdCommand = "/usr/src/app/lib/pmd/bin/run.sh pmd -d ${filesToAnalyse} -f codeclimate -R ${ruleset} -l apex -v 35"

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

def process = pmdCommand.execute()
process.consumeProcessOutput(sout, serr)
process.waitForProcessOutput()

System.out << sout.toString()
System.exit(0)
Run Code Online (Sandbox Code Playgroud)

Emm*_*osa 6

文件指出consumeProcessOutput()...

从进程获取输出和错误流并读取它们,以防止进程因输出缓冲区已满而阻塞。处理后的流数据将附加到提供的 OutputStream。为此,启动了两个线程,因此该方法将立即返回。

到目前为止,一切都很好。这是重要的部分...

即使调用 waitFor(),线程也不会进行 join()。

以及解决方案...

要等待输出被完全消耗,请调用 waitForProcessOutput()。

所以你能做的就是替换process.waitFor()process.waitForProcessOutput().