¿Es posible capturar la salida estándar del comando sh DSL en la canalización?

92

Por ejemplo:

var output=sh "echo foo";
echo "output=$output";

Obtendré:

output=0

Entonces, aparentemente obtengo el código de salida en lugar del stdout. ¿Es posible capturar la salida estándar en una variable de canalización, de modo que pueda obtener: output=foo como mi resultado?

Jesse S
fuente

Respuestas:

227

Ahora , el shpaso admite devolver stdout al proporcionar el parámetro returnStdout.

// These should all be performed at the point where you've
// checked out your sources on the slave. A 'git' executable
// must be available.
// Most typical, if you're not cloning into a sub directory
gitCommit = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
// short SHA, possibly better for chat notifications, etc.
shortCommit = gitCommit.take(6)

Vea este ejemplo .

iloahz
fuente
10
tenga en cuenta la .trim()parte de esta respuesta; de lo contrario, puede obtener un carácter de nueva línea al final de la línea
Will Munn
2
añadir --shorta rev-parsepuede obtener directamente un hash corto
Leon
No estoy seguro de qué causa la falla, pero tuve que convertir la salida a una cadena también de esta maneragitCommit = sh(returnStdout: true, script: 'git rev-parse HEAD').toString().trim()
Balkrishna
hola, ¿qué significa '.take (6)'?
Vano
1
@Vano que se refiere al método Groovy take (), que obtendrá los primeros 6 caracteres en este caso. docs.groovy-lang.org/docs/groovy-2.3.2/html/api/org/codehaus/…
ahillman3
47

Nota: Desde entonces se ha resuelto el problema relacionado con Jenkins.

Como se menciona en JENKINS-26133, no fue posible obtener la salida del shell como variable. Como solución alternativa, se sugirió el uso de escritura y lectura desde un archivo temporal. Entonces, su ejemplo se habría visto así:

sh "echo foo > result";
def output=readFile('result').trim()
echo "output=$output";
Andrey Prokopiev
fuente
21
Para los recién llegados, consulte la respuesta stackoverflow.com/a/38912813/345845 a continuación, esto se hizo más fácil con el nuevo returnStdoutparámetro pasado al shpaso.
Baptiste Mathus
2
"no es posible obtener la salida del shell como una variable", no es cierto. Esto es un truco, la respuesta correcta es returnStdout.
Graham
4
La única vez que esta es una buena respuesta es si necesita tanto el comando de shell stdoutcomo el exit statusde la shell. Otras veces, use el returnStdoutparámetro.
Simon Forsberg
4

Prueba esto:

def get_git_sha(git_dir='') {
    dir(git_dir) {
        return sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
    }
}

node(BUILD_NODE) {
    ...
    repo_SHA = get_git_sha('src/FooBar.git')
    echo repo_SHA
    ...
}

Probado en:

  • Jenkins ver. 2.19.1
  • Pipeline 2.4
METAJIJI
fuente
3

También puede intentar utilizar estas funciones para capturar StdErr StdOut y el código de retorno.

def runShell(String command){
    def responseCode = sh returnStatus: true, script: "${command} &> tmp.txt" 
    def output =  readFile(file: "tmp.txt")

    if (responseCode != 0){
      println "[ERROR] ${output}"
      throw new Exception("${output}")
    }else{
      return "${output}"
    }
}

Darse cuenta:

&>name means 1>name 2>name -- redirect stdout and stderr to the file name
GalloCedrone
fuente
1

Una versión corta sería:

echo sh(script: 'ls -al', returnStdout: true).result
A. Hab
fuente
0

Tuve el mismo problema y probé casi todo lo que encontré después de saber que lo estaba probando en el bloque equivocado. Lo estaba probando en el bloque de pasos, mientras que debe estar en el bloque de entorno.

        stage('Release') {
                    environment {
                            my_var = sh(script: "/bin/bash ${assign_version} || ls ", , returnStdout: true).trim()
                                }
                    steps {                                 
                            println my_var
                            }
                }
Nusrat ul Hassan
fuente