2012-06-19 12 views
30

Estoy intentando implementar una tarea gradle para crear dinámicamente un archivo buildsignature.properties a partir de una serie de valores de variables de entorno y ejecuciones de shell. Lo tengo funcionando principalmente, pero parece que no puedo obtener el resultado de los comandos de la shell. Aquí está mi tarea ...Cómo usar la salida exec() en gradle

task generateBuildSignature << { 
    ext.whoami = exec() { 
     executable = "whoami" 
    } 
    ext.hostname = exec() { 
     executable = "hostname" 
    } 
    ext.buildTag = System.env.BUILD_TAG ?: "dev" 

    ant.propertyfile(
     file: "${buildDir}/buildsignature.properties", 
     comment: "This file is automatically generated - DO NOT EDIT!") { 
     entry(key: "version", value: "${project.version}") 
     entry(key: "buildTimestamp", value: "${new Date().format('yyyy-MM-dd HH:mm:ss z')}") 
     entry(key: "buildUser", value: "${ext.whoami}") 
     entry(key: "buildSystem", value: "${ext.hostname}") 
     entry(key: "buildTag", value: "$ext.buildTag") 
    } 
} 

Pero el campo de propiedades resultante no obtener los resultados deseados para buildUser y buildSystem.

#This file is automatically generated - DO NOT EDIT! 
#Mon, 18 Jun 2012 18:14:14 -0700 
version=1.1.0 
buildTimestamp=2012-06-18 18\:14\:14 PDT 
buildUs[email protected]2e6a54f9 
buildSyst[email protected]46f0bf3d 
buildTag=dev 

¿Cómo llego buildUser y buildSystem para que coincida con la salida del ejecutivo correspondiente en lugar de algún defecto ExecResultImpl toString? Esto realmente no puede ser tan difícil, ¿verdad?

Respuesta

28

Este post describe cómo analizar el resultado de una invocación Exec. A continuación encontrará dos tareas que ejecutan sus comandos.

task setWhoamiProperty { 
    doLast { 
     new ByteArrayOutputStream().withStream { os -> 
      def result = exec { 
       executable = 'whoami' 
       standardOutput = os 
      } 
      ext.whoami = os.toString() 
     } 
    } 
} 

task setHostnameProperty { 
    doLast { 
     new ByteArrayOutputStream().withStream { os -> 
      def result = exec { 
       executable = 'hostname' 
       standardOutput = os 
      } 
      ext.hostname = os.toString() 
     } 
    } 
} 

task printBuildInfo { 
    dependsOn setWhoamiProperty, setHostnameProperty 
    doLast { 
     println whoami 
     println hostname 
    } 
} 

En realidad, hay una manera más fácil de obtener esta información sin tener que invocar un comando de shell.

usuario actualmente conectado: System.getProperty('user.name')

nombre de host: InetAddress.getLocalHost().getHostName()

+0

Fácil es mejor. Realmente no esperaba que la captura de la salida de un comando de shell requiera analizar manualmente una secuencia de salida. No importa. Gracias por la guía. –

+3

Pregunta rápida, ¿no le falta el código 'standardOutput = os' ?? –

+0

Cuando hacemos esto, parece ser asincrónico. Intenta dar salida a whoami y al nombre de host antes de que existan. Ideas? –

50

Ésta es mi sintaxis preferida para conseguir la salida estándar del ejecutivo:

def stdout = new ByteArrayOutputStream() 
exec{ 
    commandLine "whoami" 
    standardOutput = stdout; 
} 
println "Output:\n$stdout"; 

encontrado aquí: http://gradle.1045684.n5.nabble.com/external-process-execution-td1431883.html (Tenga en cuenta que la página tiene un error tipográfico y menciona ByteArrayInputStream en lugar de ByteArrayOutputStream)

+0

gradle 3.3: esto no está funcionando. Si comento println, no pasa nada, si lo descomente, hay muchas líneas nuevas en el resultado, es extraño pero incluso no hay palabra de "Salida" – Tertium

2

parafraseado de la Gradle docs for Exec:

task execSomething { 
    exec { 
    workingDir '/some/dir' 
    commandLine '/some/command', 'arg' 

    ... 
    //store the output instead of printing to the console: 
    standardOutput = new ByteArrayOutputStream() 

    //extension method execSomething.output() can be used to obtain the output: 
    ext.output = { 
     return standardOutput.toString() 
    } 
    } 
} 
Cuestiones relacionadas