यदि कोई कमांड विफल रहता है, तो उसे रोकना मत, लेकिन बाहर निकलने की स्थिति की जांच करें


22

मैं GNU मेक 3.81 को निर्देश देने की कोशिश कर रहा हूं कि अगर कोई कमांड विफल रहता है (तो मैं कमांड के साथ उपसर्ग करता -हूं), लेकिन मैं अगले कमांड पर बाहर निकलने की स्थिति की जांच करना चाहता हूं और अधिक जानकारीपूर्ण संदेश प्रिंट करना चाहता हूं। हालांकि मेरा मेकफाइल नीचे विफल रहता है:

$ cat Makefile 
all:
    -/bin/false
    ([ $$? -eq 0 ] && echo "success!") || echo "failure!"
$
$ make
/bin/false
make: [all] Error 1 (ignored)
([ $? -eq 0 ] && echo "success!") || echo "failure!"
success!

क्यों गूंज से ऊपर Makefile "सफलता!" इसके बजाय "विफलता!" ?

अद्यतन करें:

निम्नलिखित स्वीकार किए गए उत्तर पर विस्तार और विस्तार किया गया है, नीचे लिखा गया है:

failure:                                                                                                                                                                                                                                      
    @-/bin/false && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"                                                                                                                                                                 
success:                                                                                                                                                                                                                                      
    @-/bin/true && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"     

2
आप .ONESHELL:निर्देश की जांच कर सकते हैं ।
जोनाथन लेफ़लर

.ONESHELL एक शेल में सभी रसीद ब्लॉक चलाएगी जिसका प्रभाव है: यदि पहली कमांड विफल रहती है, तो अगले को बिना किसी समस्या के निष्पादित किया जाएगा। इसे रोकने के .SHELLFLAGS = -ecलिए इस्तेमाल किया जाना चाहिए। लेकिन इस मामले में आप -उपसर्ग का उपयोग नहीं कर सकते हैं (रसीद की व्यक्तिगत कमांड के लिए) क्योंकि मेक लिखेगा कि त्रुटि को अनदेखा किया गया है लेकिन फिर भी सभी ब्लॉक को विफल कर देगा। तो, || :कमांड को अनदेखा करने का एक उपाय है। लेकिन यह क्रॉस-प्लेटफ़ॉर्म नहीं है (विंडोज ने नहीं किया है || :या नहीं || true)
पॉल-एजी

जवाबों:


14

Makefile नियम में प्रत्येक अद्यतन कमांड को एक अलग शेल में निष्पादित किया जाता है। तो $? पिछले विफल आदेश की निकास स्थिति नहीं है, इसमें $ के लिए डिफ़ॉल्ट मान जो भी है? एक नए खोल में। यही कारण है कि आपका [$? -एक ०] परीक्षण हमेशा सफल होता है।


10

आप की कसौटी पर की जरूरत नहीं है $?के बाद से &&काम करता है, तो $?शून्य है और ||एक गैर शून्य वापसी मान के मामले में आगे बढ़ना है।

और आपको लाइन के अंतिम कार्यवाही प्रोग्राम कॉल से लेने के लिए वापसी मूल्य पर ऋण की आवश्यकता नहीं है। तो यह ठीक काम करता है

विफलता:

      @/bin/false && echo "success!" || echo "failure!" 

सफलता:

      @/bin/true && echo "success!" || echo "failure!"

इसके विपरीत होता है: यदि आप अपना संदेश स्वयं करना चाहते हैं और किसी भी तरह से गैर-शून्य मान के साथ प्रक्रिया बनाना चाहते हैं, तो आपको कुछ इस तरह लिखना होगा:

विफलता:

      @/bin/false && echo "success!" || { echo "failure!"; exit 1; }

8

जीएनयू से प्रलेखन करें :

जब त्रुटियों को अनदेखा किया जाता है, तो '-' या '-i' ध्वज के कारण, सफलता की तरह ही एक त्रुटि वापसी का व्यवहार करता है , सिवाय इसके कि यह एक संदेश प्रिंट करता है जो आपको बताए गए स्थिति कोड को खोल के साथ बाहर निकलता है, और कहते हैं कि त्रुटि को नजरअंदाज कर दिया गया है।

makeइस तरह से एक मामले में बाहर निकलने की स्थिति का उपयोग करने के लिए , makeएक स्क्रिप्ट से निष्पादित करें :

#!/bin/bash
make
([ $? -eq 0 ] && echo "success!") || echo "failure!"

और अपने Makefile होते हैं:

all:
    /bin/false
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.