Est-il possible de capturer le stdout à partir de la commande sh DSL dans le pipeline


92

Par exemple:

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

J'aurai:

output=0

Donc, apparemment, j'obtiens le code de sortie plutôt que le stdout. Est-il possible de capturer le stdout dans une variable de pipeline, de sorte que je puisse obtenir: output=foo comme résultat?

Réponses:


227

Maintenant , l' shétape prend en charge le retour de stdout en fournissant le paramètre 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)

Voyez cet exemple .


10
notez la .trim()partie de cette réponse, sinon vous risquez d'obtenir un caractère de nouvelle ligne à la fin de la ligne
Will Munn

2
ajouter --shortà rev-parsepeut simplement obtenir directement un hachage court
Leon

Je ne sais pas ce qui a causé l'échec, mais j'ai dû convertir la sortie en chaîne comme celle-cigitCommit = sh(returnStdout: true, script: 'git rev-parse HEAD').toString().trim()
Balkrishna

salut, que signifie «.take (6)»?
Vano

1
@Vano qui fait référence à la méthode Groovy take (), qui récupérera les 6 premiers caractères dans ce cas. docs.groovy-lang.org/docs/groovy-2.3.2/html/api/org/codehaus/…
ahillman3

47

Remarque: le problème lié à Jenkins a depuis été résolu.

Comme mentionné dans JENKINS-26133, il n'était pas possible d'obtenir la sortie du shell en tant que variable. Comme solution de contournement suggérée l'utilisation de la lecture en écriture à partir d'un fichier temporaire. Donc, votre exemple aurait ressemblé à:

sh "echo foo > result";
def output=readFile('result').trim()
echo "output=$output";

21
Pour les nouveaux arrivants, veuillez consulter la réponse stackoverflow.com/a/38912813/345845 ci-dessous, cela a depuis été facilité avec le nouveau returnStdoutparamètre passé à l' shétape.
Baptiste Mathus

2
"il n'est pas possible d'obtenir la sortie du shell en tant que variable" - ce n'est pas vrai. Ceci est un hack, la bonne réponse est returnStdout.
Graham

4
La seule fois où c'est une bonne réponse, c'est si vous avez besoin à la fois de la commande stdoutet exit statusde la commande du shell. D'autres fois, utilisez le returnStdoutparamètre.
Simon Forsberg

4

Essaye ça:

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
    ...
}

Testé sur:

  • Jenkins ver. 2.19.1
  • Pipeline 2.4

3

Vous pouvez également essayer d'utiliser ces fonctions pour capturer StdErr StdOut et retourner le code.

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}"
    }
}

Remarquer:

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

1

Une version courte serait:

echo sh(script: 'ls -al', returnStdout: true).result


0

J'ai eu le même problème et j'ai essayé presque tout ce que j'ai trouvé après avoir appris que je l'essayais dans le mauvais bloc. Je l'ai essayé en bloc d'étapes alors qu'il doit être dans le bloc d'environnement.

        stage('Release') {
                    environment {
                            my_var = sh(script: "/bin/bash ${assign_version} || ls ", , returnStdout: true).trim()
                                }
                    steps {                                 
                            println my_var
                            }
                }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.