Groovy exec 缓冲输出 - 在批处理文件完成之前不打印
Groovy exec buffering output - not printing until batch file completes
从 Groovy 执行 bat 文件时,在 bat 文件完成之前不会从 Groovy 脚本打印输出。为了进行比较,我测试了来自 C# 和 Perl 的完全相同的 bat 文件。这些都在将 bat 文件写入 STDOUT 时打印输出。
def cmd = "batfile.bat param1"
println cmd.execute().text()
有没有办法告诉Groovy读取流并立即打印?
感谢您的回复!我还要注意的是,在使用建议时,exec 没有等待进程完成,在这种情况下我们希望如此,因此添加 process.waitFor() 完成了这一点。下面的工作代码示例。 (注意test.bat随便你,比如:sleep 5)
import groovy.time.*
def times = [:]
def progStartTime = new Date()
String[] caches = ["cache1", "cache2", "cache3"]
def cmd
def batFile = "test.bat "
println new Date()
for (String item : caches) {
def timeStart = new Date()
cmd = [batFile, item]
//println cmd.execute().text
def process = cmd.execute()
process.consumeProcessOutput(System.out, System.err)
process.waitFor()
def timeStop = new Date()
TimeDuration duration = TimeCategory.minus(timeStop, timeStart)
println "cache: " + item + " : " + duration
times.put(item,duration)
}
times.each{ k, v -> println "cache: ${k}, took: ${v}" }
def progStopTime = new Date()
TimeDuration duration = TimeCategory.minus(progStopTime, progStartTime)
println "Total Program duration: " + duration
println new Date()
首先我认为它应该是:
cmd.execute().text
没有括号所以我们调用了groovyProcess.getText()方法。但是,这不会解决您的问题,因为 getText() 方法在返回之前等待进程完成。
如果你不需要控制输出而只是想直接在标准输出和标准错误上输出,你可以使用groovy Process.consumeProcessOutput()方法:
def process = "batfile.bat param1".execute()
process.consumeProcessOutput(System.out, System.err)
当输出可用时,这将直接在系统输出和错误流上输出进程输出和错误流输出。
如果您需要处理或控制,类似以下内容应该可以解决您的问题:
def process = "batfile.bat param1".execute()
process.in.withReader { r ->
r.eachLine { line ->
// some token processing
println "batfile output> ${line.toUpperCase()}"
}
}
带空格的参数也容易造成破坏,所以我发现使用 groovy List.execute() 形式通常更安全,例如:
def process = ["batfile.bat", "param1"].execute()
它做同样的事情,但保持关于空格的参数完整性。
从 Groovy 执行 bat 文件时,在 bat 文件完成之前不会从 Groovy 脚本打印输出。为了进行比较,我测试了来自 C# 和 Perl 的完全相同的 bat 文件。这些都在将 bat 文件写入 STDOUT 时打印输出。
def cmd = "batfile.bat param1"
println cmd.execute().text()
有没有办法告诉Groovy读取流并立即打印?
感谢您的回复!我还要注意的是,在使用建议时,exec 没有等待进程完成,在这种情况下我们希望如此,因此添加 process.waitFor() 完成了这一点。下面的工作代码示例。 (注意test.bat随便你,比如:sleep 5)
import groovy.time.*
def times = [:]
def progStartTime = new Date()
String[] caches = ["cache1", "cache2", "cache3"]
def cmd
def batFile = "test.bat "
println new Date()
for (String item : caches) {
def timeStart = new Date()
cmd = [batFile, item]
//println cmd.execute().text
def process = cmd.execute()
process.consumeProcessOutput(System.out, System.err)
process.waitFor()
def timeStop = new Date()
TimeDuration duration = TimeCategory.minus(timeStop, timeStart)
println "cache: " + item + " : " + duration
times.put(item,duration)
}
times.each{ k, v -> println "cache: ${k}, took: ${v}" }
def progStopTime = new Date()
TimeDuration duration = TimeCategory.minus(progStopTime, progStartTime)
println "Total Program duration: " + duration
println new Date()
首先我认为它应该是:
cmd.execute().text
没有括号所以我们调用了groovyProcess.getText()方法。但是,这不会解决您的问题,因为 getText() 方法在返回之前等待进程完成。
如果你不需要控制输出而只是想直接在标准输出和标准错误上输出,你可以使用groovy Process.consumeProcessOutput()方法:
def process = "batfile.bat param1".execute()
process.consumeProcessOutput(System.out, System.err)
当输出可用时,这将直接在系统输出和错误流上输出进程输出和错误流输出。
如果您需要处理或控制,类似以下内容应该可以解决您的问题:
def process = "batfile.bat param1".execute()
process.in.withReader { r ->
r.eachLine { line ->
// some token processing
println "batfile output> ${line.toUpperCase()}"
}
}
带空格的参数也容易造成破坏,所以我发现使用 groovy List.execute() 形式通常更安全,例如:
def process = ["batfile.bat", "param1"].execute()
它做同样的事情,但保持关于空格的参数完整性。