groovy - los - comandos shell windows
Groovy ejecutando comandos de shell (7)
Groovy agrega el método de execute
a String
para facilitar la ejecución de shells;
println "ls".execute().text
pero si ocurre un error, entonces no hay salida resultante. ¿Hay alguna manera fácil de obtener el error estándar y el estándar? (además de crear un montón de código para: crear dos hilos para leer ambos flujos de entrada, luego usar una secuencia principal para esperar a que se completen y luego convertir las cadenas de nuevo en texto?)
Sería bueno tener algo así como;
def x = shellDo("ls /tmp/NoFile")
println "out: ${x.out} err:${x.err}"
Encuentro esto más idiomático:
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"
Como se menciona en otra publicación, estas son llamadas de bloqueo, pero dado que queremos trabajar con la salida, esto puede ser necesario.
Ok, lo resolví yo mismo;
def sout = new StringBuilder(), serr = new StringBuilder()
def proc = ''ls /badDir''.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"
muestra:
out> err> ls: cannot access /badDir: No such file or directory
Para agregar una información más importante a las respuestas proporcionadas anteriormente,
Para un proceso
def proc = command.execute();
siempre trata de usar
def outputStream = new StringBuffer();
proc.waitForProcessOutput(outputStream, System.err)
//proc.waitForProcessOutput(System.out, System.err)
más bien que
def output = proc.in.text;
para capturar las salidas después de ejecutar comandos en groovy ya que este último es una llamada de bloqueo ( pregunta de SO por razones ).
"ls".execute()
devuelve un objeto de Process
lo que "ls".execute().text
funciona. Debería poder leer la secuencia de error para determinar si hubo algún error.
Hay un método adicional en Process
que le permite pasar un StringBuffer
para recuperar el texto: consumeProcessErrorStream(StringBuffer error)
.
Ejemplo:
def proc = "ls".execute()
def b = new StringBuffer()
proc.consumeProcessErrorStream(b)
println proc.text
println b.toString()
// 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()
}
command = "ls *"
def execute_state=sh(returnStdout: true, script: command)
pero si la falla del comando el proceso terminará
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]