有没有办法将长 Groovy execute() 命令的输出流式传输到控制台,而不是等待它完成?
Is there a way to stream the output of a long Groovy execute() command to the console rather than wait for it to finish?
我是 运行 通过系统 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}"
}
这是我找到的解决方案。
proc.in.eachLine { line -> println line }
proc.out.close()
proc.waitFor()
虽然您找到的解决方案可能工作正常,但我认为最好使用 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 上执行外部进程。
经过长时间的搜索,我无法得到确切的解决方案。这对我有用:
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()
}
以下脚本有效:
def pmdCommand = "java -cp D:\Users\user1\work\backup\work\LOG-SHELL-FIX\EAR\Encrypter.jar com.mdm.custom.main.Encrypter password123 ${publicKey}"
def sout = new StringBuffer()
def serr = new StringBuffer()
Process process = pmdCommand.execute()
process.waitForProcessOutput(sout,serr) // This is a better way to read the output
if(sout.size()>0) log.info "$sout"
if(serr.size()>0) log.info "$serr"
Groovy 方法参考位于:http://docs.groovy-lang.org/docs/groovy-latest/html/api/org/codehaus/groovy/runtime/ProcessGroovyMethods.html
我是 运行 通过系统 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}"
}
这是我找到的解决方案。
proc.in.eachLine { line -> println line }
proc.out.close()
proc.waitFor()
虽然您找到的解决方案可能工作正常,但我认为最好使用 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 上执行外部进程。
经过长时间的搜索,我无法得到确切的解决方案。这对我有用:
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()
}
以下脚本有效:
def pmdCommand = "java -cp D:\Users\user1\work\backup\work\LOG-SHELL-FIX\EAR\Encrypter.jar com.mdm.custom.main.Encrypter password123 ${publicKey}"
def sout = new StringBuffer()
def serr = new StringBuffer()
Process process = pmdCommand.execute()
process.waitForProcessOutput(sout,serr) // This is a better way to read the output
if(sout.size()>0) log.info "$sout"
if(serr.size()>0) log.info "$serr"
Groovy 方法参考位于:http://docs.groovy-lang.org/docs/groovy-latest/html/api/org/codehaus/groovy/runtime/ProcessGroovyMethods.html