好的,我自己解决了。
def sout = new StringBuilder(), serr = new StringBuilder()
def proc = 'ls /badDir'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout\nerr> $serr"
显示:
out> err> ls: 无法访问 / badDir:没有那个文件或目录
envVars = ["P4PORT=p4server:2222", "P4USER=user", "P4PASSWD=pass", "P4CLIENT=p4workspace"]; workDir = new File("path"); cmd = "bash -c \"p4 change -o 1234\""; proc = cmd.execute(envVars, workDir);
- Noam Manos"ls".execute()
返回一个 Process
对象,这就是为什么 "ls".execute().text
起作用的原因。你应该能够仅通过读取错误流来确定是否有任何错误。
Process
上还有一个额外的方法,允许你传递一个 StringBuffer
来检索文本:consumeProcessErrorStream(StringBuffer error)
。
示例:
def proc = "ls".execute()
def b = new StringBuffer()
proc.consumeProcessErrorStream(b)
println proc.text
println b.toString()
我觉得这种表达更符合惯用语:
def proc = "ls foo.txt doesnotexist.txt".execute()
assert proc.in.text == "foo.txt\n"
assert proc.err.text == "ls: doesnotexist.txt: No such file or directory\n"
正如另一篇帖子所提到的,这些都是阻塞调用,但由于我们想要处理输出,这可能是必要的。
// a wrapper closure around executing a string
// can take either a string or a list of strings (for arguments with spaces)
// prints all output, complains and halts on error
def runCommand = { strList ->
assert ( strList instanceof String ||
( strList instanceof List && strList.each{ it instanceof String } ) \
)
def proc = strList.execute()
proc.in.eachLine { line -> println line }
proc.out.close()
proc.waitFor()
print "[INFO] ( "
if(strList instanceof List) {
strList.each { print "${it} " }
} else {
print strList
}
println " )"
if (proc.exitValue()) {
println "gave the following error: "
println "[ERROR] ${proc.getErrorStream()}"
}
assert !proc.exitValue()
}
runCommand("echo HELLO WORLD")
- Miron Veryanskiy在之前的回答中,再添加一条重要信息:
对于一个进程
def proc = command.execute();
始终尝试使用
def outputStream = new StringBuffer();
proc.waitForProcessOutput(outputStream, System.err)
//proc.waitForProcessOutput(System.out, System.err)
而不是
def output = proc.in.text;
在Groovy中执行命令时,要捕获输出结果,因为后者是阻塞调用(关于原因的SO问题)。
def exec = { encoding, execPath, execStr, execCommands ->
def outputCatcher = new ByteArrayOutputStream()
def errorCatcher = new ByteArrayOutputStream()
def proc = execStr.execute(null, new File(execPath))
def inputCatcher = proc.outputStream
execCommands.each { cm ->
inputCatcher.write(cm.getBytes(encoding))
inputCatcher.flush()
}
proc.consumeProcessOutput(outputCatcher, errorCatcher)
proc.waitFor()
return [new String(outputCatcher.toByteArray(), encoding), new String(errorCatcher.toByteArray(), encoding)]
}
def out = exec("cp866", "C:\\Test", "cmd", ["cd..\n", "dir\n", "exit\n"])
println "OUT:\n" + out[0]
println "ERR:\n" + out[1]
command = "ls *"
def execute_state=sh(returnStdout: true, script: command)
但如果命令失败,进程将终止。
sh
是从“shell”(壳层)一词中衍生出来的。 - Jerry U