Apakah mungkin untuk menangkap stdout dari perintah sh DSL di pipeline

92

Sebagai contoh:

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

Saya akan mendapatkan:

output=0

Jadi, ternyata saya mendapatkan kode keluar daripada stdout. Apakah mungkin untuk menangkap stdout menjadi variabel pipeline, sehingga saya bisa mendapatkan: output=foo sebagai hasil saya?

Jesse S
sumber

Jawaban:

227

Sekarang , shlangkah tersebut mendukung pengembalian stdout dengan menyediakan parameter 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)

Lihat contoh ini .

iloahz
sumber
10
perhatikan .trim()bagian dari jawaban ini, jika tidak, Anda mungkin mendapatkan karakter baris baru di akhir baris
Will Munn
2
tambahkan --shortke rev-parsebisa langsung mendapatkan hash pendek
Leon
tidak yakin apa yang menyebabkan kegagalan tetapi saya harus mengonversi output ke string juga seperti inigitCommit = sh(returnStdout: true, script: 'git rev-parse HEAD').toString().trim()
Balkrishna
hai, apa kepanjangan dari '.take (6)'?
Vano
1
@Vano yang mengacu pada metode Groovy take (), yang akan mendapatkan 6 karakter pertama dalam kasus ini. docs.groovy-lang.org/docs/groovy-2.3.2/html/api/org/codehaus/…
ahillman3
47

Catatan: Masalah Jenkins tertaut telah diselesaikan sejak saat itu.

Seperti yang disebutkan dalam JENKINS-26133 , tidak mungkin mendapatkan keluaran shell sebagai variabel. Sebagai solusinya disarankan menggunakan write-read dari file sementara. Jadi, contoh Anda akan terlihat seperti ini:

sh "echo foo > result";
def output=readFile('result').trim()
echo "output=$output";
Andrey Prokopiev
sumber
21
Untuk pendatang baru, silakan lihat jawaban stackoverflow.com/a/38912813/345845 di bawah ini, karena ini dipermudah dengan returnStdoutparameter baru yang diteruskan ke shlangkah.
Baptiste Mathus
2
"tidak mungkin mendapatkan keluaran shell sebagai variabel" - tidak benar. Ini hack, jawaban yang benar adalah returnStdout.
Graham
4
Satu-satunya saat ini sebenarnya jawaban yang baik adalah jika Anda perlu baik yang stdoutdan exit statusdari perintah shell. Di lain waktu, gunakan returnStdoutparameter.
Simon Forsberg
4

Coba ini:

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

Diuji pada:

  • Jenkins ver. 2.19.1
  • Pipa 2.4
METAJIJI
sumber
3

Anda juga dapat mencoba menggunakan fungsi ini untuk menangkap StdErr StdOut dan mengembalikan kode.

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

Memperhatikan:

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

Versi singkatnya adalah:

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

Saya memiliki masalah yang sama dan mencoba hampir semua hal yang kemudian saya temukan setelah saya mengetahui bahwa saya mencobanya di blok yang salah. Saya mencobanya di blok langkah sedangkan itu perlu di blok lingkungan.

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