मुझे जेनकिंसफाइल (ग्रूवी) से चर में उपयोग करके निष्पादित शेल कमांड का आउटपुट कैसे मिलेगा?


213

मेरे पास जेनकिंसफाइल (ग्रूवी) पर ऐसा कुछ है और मैं बाद में सूचना का उपयोग करने के लिए एक चर में स्टडआउट और निकास कोड रिकॉर्ड करना चाहता हूं।

sh "ls -l"

मैं यह कैसे कर सकता हूं, विशेष रूप से ऐसा लगता है कि आप वास्तव में किसी भी प्रकार के ग्रूवी कोड को अंदर नहीं चला सकते हैं Jenkinsfile?



जवाबों:


391

पाइपलाइन shचरण का नवीनतम संस्करण आपको निम्नलिखित करने की अनुमति देता है;

// Git committer email
GIT_COMMIT_EMAIL = sh (
    script: 'git --no-pager show -s --format=\'%ae\'',
    returnStdout: true
).trim()
echo "Git committer email: ${GIT_COMMIT_EMAIL}"

एक अन्य विशेषता returnStatusविकल्प है।

// Test commit message for flags
BUILD_FULL = sh (
    script: "git log -1 --pretty=%B | grep '\\[jenkins-full]'",
    returnStatus: true
) == 0
echo "Build full flag: ${BUILD_FULL}"

इस विकल्प को इस मुद्दे के आधार पर कहां जोड़ा गया है ।

कमांड के लिए आधिकारिक दस्तावेज देखें sh


11
अब ऐसा लगता है कि यह प्रलेखित है -> jenkins.io/doc/pipeline/steps/workflow-durable-task-step/…
zot24

हालांकि "var" उपसर्ग के साथ मेरे लिए काम नहीं करता है। जब मैं सिर्फ उपसर्ग के बिना GIT_COMMIT_EMAIL का उपयोग करता हूं, तो सब ठीक है।
बैस्टियन वोइगट


7
जब मैं घोषणात्मक जेनकिंसफाइल सिंटैक्स का उपयोग कर रहा हूं, तो यह काम नहीं करता है, त्रुटि संदेश है:WorkflowScript: 97: Expected a step @ line 97, column 17.
रिंच

17
ऐसा लगता है कि यह केवल एक scriptकदम ब्लॉक के अंदर काम करता है । jenkins.io/doc/book/pipeline/syntax/#declarative-steps
पीतल बंदर

51

वर्तमान पाइपलाइन संस्करण मूल रूप से समर्थन करता है returnStdoutऔर returnStatus, जो sh/ batचरणों से आउटपुट या स्थिति प्राप्त करना संभव बनाता है ।

एक उदाहरण:

def ret = sh(script: 'uname', returnStdout: true)
println ret

एक आधिकारिक दस्तावेज


क्या कोई मुझे stackoverflow.com/questions/40946697/… के लिए मदद कर सकता है ? अग्रिम में धन्यवाद!
जितेश सोजित्रा

3
बयानों को एक script { }चरण में लपेटा जाना है ।
x-yuri

40

त्वरित उत्तर यह है:

sh "ls -l > commandResult"
result = readFile('commandResult').trim()

मुझे लगता है कि श स्टेप का परिणाम प्राप्त करने में सक्षम होने के लिए एक सुविधा अनुरोध मौजूद है, लेकिन जहां तक ​​मुझे पता है, वर्तमान में कोई अन्य विकल्प नहीं है।

EDIT: JENKINS-26133

EDIT2: अभी तक निश्चित नहीं है कि किस संस्करण से, लेकिन श / बल्ला कदम अब std आउटपुट वापस कर सकते हैं, बस:

def output = sh returnStdout: true, script: 'ls -l'

1
इसके अलावा FYI, बैट स्टेप्स कमांड को चलाया जा रहा है, इसलिए आपको आउटपुट प्राप्त करने के लिए @ के साथ बैट कमांड शुरू करने की आवश्यकता है (उदाहरण के लिए "@dir")।
रसेल गैलप

21

यदि आप स्टैडआउट प्राप्त करना चाहते हैं और यह जानते हैं कि कमांड सफल हुआ या नहीं, बस returnStdoutएक अपवाद हैंडलर में इसका उपयोग करें और इसे लपेटें:

स्क्रिप्टेड पाइपलाइन

try {
    // Fails with non-zero exit if dir1 does not exist
    def dir1 = sh(script:'ls -la dir1', returnStdout:true).trim()
} catch (Exception ex) {
    println("Unable to read dir1: ${ex}")
}

आउटपुट :

[Pipeline] sh
[Test-Pipeline] Running shell script
+ ls -la dir1
ls: cannot access dir1: No such file or directory
[Pipeline] echo
unable to read dir1: hudson.AbortException: script returned exit code 2

दुर्भाग्य से hudson.AbortException उस निकास स्थिति को प्राप्त करने के लिए किसी भी उपयोगी विधि को याद कर रही है, इसलिए यदि वास्तविक मूल्य की आवश्यकता है तो आपको इसे संदेश से बाहर पार्स करने की आवश्यकता होगी (ugh!)

Javadoc के विपरीत https://javadoc.jenkins-ci.org/hudson/AbortException.html यह अपवाद पकड़े जाने पर बिल्ड विफल नहीं है। यह तब विफल हो जाता है जब यह पकड़ा नहीं जाता है !

अद्यतन: यदि आप भी शेल कमांड से STDERR आउटपुट चाहते हैं, तो जेनकिंस दुर्भाग्य से उस सामान्य उपयोग के मामले का ठीक से समर्थन करने में विफल रहता है। 2017 का टिकट JENKINS-44930 एक समाधान की दिशा में कोई प्रगति नहीं करते हुए, विचारित पिंग-पोंग की स्थिति में फंस गया है - कृपया इसमें अपने उत्थान को जोड़ने पर विचार करें।

अब एक समाधान के रूप में , संभव दृष्टिकोण के एक जोड़े हो सकता है:

a) STDERR को STDOUT में रीडायरेक्ट करें 2>&1 - लेकिन यह आपके लिए है कि मुख्य आउटपुट से बाहर पार्स करें, और कमांड के विफल होने पर आपको आउटपुट नहीं मिलेगा - क्योंकि आप अपवाद हैंडलर में हैं।

b) STDERR को एक अस्थायी फ़ाइल (जिसका नाम आप पहले तैयार करते हैं) पर पुनर्निर्देशित करें 2>filename(लेकिन बाद में फ़ाइल को साफ करना याद रखें) - यानी। मुख्य कोड बन जाता है:

def stderrfile = 'stderr.out'
try {
    def dir1 = sh(script:"ls -la dir1 2>${stderrfile}", returnStdout:true).trim()
} catch (Exception ex) {
    def errmsg = readFile(stderrfile)
    println("Unable to read dir1: ${ex} - ${errmsg}")
}

ग) दूसरे तरीके से जाएं, returnStatus=trueइसके बजाय सेट करें , अपवाद हैंडलर के साथ वितरित करें और हमेशा फ़ाइल पर आउटपुट कैप्चर करें, अर्थात:

def outfile = 'stdout.out'
def status = sh(script:"ls -la dir1 >${outfile} 2>&1", returnStatus:true)
def output = readFile(outfile).trim()
if (status == 0) {
    // output is directory listing from stdout
} else {
    // output is error message from stderr
}

कैविएट: उपरोक्त कोड यूनिक्स / लिनक्स-विशिष्ट है - विंडोज के लिए पूरी तरह से अलग शेल कमांड की आवश्यकता होती है।


1
क्या आउटपुट प्राप्त करने का एक मौका है "ls: can access dir1: No no file or directory" और इतना ही नहीं "hudson.AbortException: script रिटर्न एग्जिट कोड 2"?
user2988257

मैं नहीं देखता कि यह कभी कैसे काम कर सकता है। मेरे परीक्षण में आउटपुट टेक्स्ट को कभी भी असाइन नहीं किया गया है और यह अपेक्षित है। शेल स्टेप से फेंका गया अपवाद रिटर्न वैल्यू को असाइन करने से रोकता है
जैकब बोचेंस्की

2
रिटर्नस्टैटस और रिटर्नसटाउट दुर्भाग्य से एक ही समय में काम नहीं करते हैं। यहाँ टिकट है। कृपया, वोट करें: मुद्दोंJenkins-ci.org/browse/JENKINS-44930
अलेक्जेंडर समोयलोव

1
@AlexanderSamoylov आपको ऊपर (विकल्प) के रूप में फ़ाइल का उपयोग करके काम करना होगा। दुर्भाग्य से इन औजारों के लेखकों की राय अक्सर ली जाती है और अन्य सामान्य उपयोग के मामलों के लिए आगे नहीं सोचते हैं, यहाँ बिंदु में एक मामला है।
एड रान्डेल

1
@ ईडी रान्डेल, पूरी तरह से आपके साथ सहमत हैं .. यही कारण है कि मैंने इस मुद्दे को इस उम्मीद के साथ पोस्ट किया है कि बड़ी संख्या में वोटों के कारण वे कुछ करना शुरू करते हैं।
अलेक्जेंडर समोयलोव

12

यह एक नमूना मामला है, जो मुझे विश्वास दिलाएगा!

node('master'){
    stage('stage1'){
    def commit = sh (returnStdout: true, script: '''echo hi
    echo bye | grep -o "e"
    date
    echo lol''').split()


    echo "${commit[-1]} "

    }
}

मुझे पता नहीं है, लेकिन आपका जवाब मुझे बहुत मदद करता है, धन्यवाद :)
शारनाकाश

5

उन लोगों के लिए जिन्हें ग्रूवी के बजाय बाद के शेल कमांड में आउटपुट का उपयोग करने की आवश्यकता है, इस तरह का कुछ उदाहरण किया जा सकता है:

    stage('Show Files') {
        environment {
          MY_FILES = sh(script: 'cd mydir && ls -l', returnStdout: true)
        }
        steps {
          sh '''
            echo "$MY_FILES"
          '''
        }
    }

मुझे कोड मावेन पर उदाहरण काफी उपयोगी लगे।


-6

सबसे आसान तरीका इस तरह का उपयोग है

my_var=`echo 2` echo $my_var आउटपुट: २

ध्यान दें कि सरल एकल उद्धरण वापस बोली नहीं है (`)।


अपवोट किया गया है, लेकिन मैं आपको सुझाव दूंगा कि आपको यह दिखाना चाहिए कि ये एक shअन्यथा के तहत लिपटे होने चाहिए, लोग सोच सकते हैं कि यह ग्रूवी है, खासकर यदि वे बैश स्क्रिप्टिंग से परिचित नहीं हैं। मैंने अभी इसे जेनकिंस पर आज़माया है, ls -lइसके बजाय echo 2इसका उपयोग कर रहा है और यह काम करता है। मैंने पहले भी इस दृष्टिकोण का उपयोग किया था, लेकिन एक विकल्प की तलाश कर रहा था, क्योंकि यह बहुत विश्वसनीय नहीं है। मेरे पास इस तरह से एक मानक शेल पर कैप्चर किए गए अधिक जटिल कमांड का आउटपुट है, लेकिन जब जेनकींस को पोर्ट किया जाता है shतो चर कुछ अज्ञात कारण के लिए कुछ भी नहीं रखता है।
नागदेव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.