有没有一种方法可以将长的Groovy execute()命令的输出流传输到控制台,而不是等待它完成?

时间:2019-01-03 18:48:02

标签: jenkins groovy jenkins-groovy

我正在通过系统Groovy脚本运行Shell命令。这是一个漫长的过程,大约需要30分钟,而且非常冗长。但是正如所写的那样,它在打印stdout或stderr之前等待命令完成。有没有一种方法可以在脚本执行时将输出发送到控制台(就像在终端会话中一样)。

def sout = new StringBuffer(), serr = new StringBuffer()
def proc = "/some/long/running/command".execute()

proc.consumeProcessOutput(sout, serr)
println "STDOUT\n $sout"
println "STDERR\n $serr"

更新:这是我根据答案尝试的代码。在该过程完成或被杀死之前,它不会打印任何内容。

def cmd = "/home/adam/test.sh"
StringBuffer sout = new StringBuffer()
StringBuffer serr = new StringBuffer()
def process = cmd.execute()
process.waitForProcessOutput sout, serr
sout.each 
   println "Line ${it}"
}

3 个答案:

答案 0 :(得分:3)

虽然您发现的解决方案可能会很好地工作,但我认为最好使用waitForProcessOutput,它还允许流式传输过程的错误输出。

完整的解决方案是这样的:

#!/usr/bin/env groovy
Process proc = "ping -c 10 google.com".execute()
proc.waitForProcessOutput(System.out, System.err)
System.exit(proc.exitValue())

此方法有多种选择,例如仅捕获正常输出或仅捕获错误输出。您可以找到它们here

Groovy docs上还有一章(相当简短的一章)关于执行外部过程。

答案 1 :(得分:1)

经过长时间的搜索,我无法找到确切的解决方案。这对我有用:

public int Execute(def command, File dir) {
          println("command: ${command}")
          Process process = command.execute(null, dir)
          def out = new StringBuffer()
          def err = new StringBuffer()
          process.consumeProcessOutput(out, err)
          while(1) {
              err.eachLine {line, count ->
                  println("${line}")
                  err.setLength(0)
              }
              out.eachLine { line, count ->
                  println("${line}")
                  out.setLength(0)
              }
              if(! process.isAlive()) {
                  break
                  }
              }
         return process.exitValue()
         }

答案 2 :(得分:0)

这是我找到的解决方案。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero