set -e
स्क्रिप्ट को समाप्त करता है यदि कुछ शर्तों के अलावा, नॉनज़रो एग्जिट कोड का सामना करना पड़ता है। कुछ शब्दों में इसके उपयोग के खतरों को समझने के लिए: यह व्यवहार नहीं करता है कि लोग यह कैसे सोचते हैं।
मेरी राय में, इसे एक खतरनाक हैक माना जाना चाहिए जो केवल संगतता उद्देश्यों के लिए मौजूद है। यह set -e
कथन उस भाषा से शेल को चालू नहीं करता है जो त्रुटि कोड का उपयोग ऐसी भाषा में करता है जो अपवाद जैसे नियंत्रण प्रवाह का उपयोग करता है, यह केवल उस व्यवहार का अनुकरण करने का खराब प्रयास करता है।
ग्रेग वूलेज के खतरों पर बहुत कुछ कहना है set -e
:
दूसरे लिंक में, के अनपेक्षित और अप्रत्याशित व्यवहार के विभिन्न उदाहरण हैं set -e
।
के अनपेक्षित व्यवहार के कुछ उदाहरण set -e
(कुछ उपरोक्त विकि लिंक से लिया गया है):
सेट
x = 0
चलो x ++
इको "x $ x" है
उपरोक्त शेल स्क्रिप्ट समय से पहले बाहर निकलने का कारण बनेगा, क्योंकि let x++
रिटर्न 0, जिसे let
कीवर्ड द्वारा एक गलत मान के रूप में माना जाता है और एक नॉनजेरो एग्जिट कोड में बदल जाता है। set -e
यह नोटिस, और चुपचाप स्क्रिप्ट को समाप्त करता है।
सेट
[-d / opt / foo] && इको "चेतावनी: फू पहले से स्थापित है। अधिलेखित हो जाएगा।" > और 2
गूंज "संस्थापन फू ..."
उपरोक्त कार्य /opt/foo
पहले से मौजूद होने पर, चेतावनी को छापते हुए काम करता है।
सेट
check_prepret_install () {
[-d / opt / foo] && इको "चेतावनी: फू पहले से स्थापित है। अधिलेखित हो जाएगा।" > और 2
}
check_previous_install
गूंज "संस्थापन फू ..."
उपरोक्त, एकमात्र अंतर होने के बावजूद कि एक लाइन को एक फ़ंक्शन में रिफैक्ट किया गया है, /opt/foo
मौजूद नहीं होने पर समाप्त हो जाएगा । ऐसा इसलिए है क्योंकि यह तथ्य कि यह मूल रूप से काम करता है, एक विशेष अपवाद है set -e
। जब a && b
नॉनजरो लौटता है, तो इसे नजरअंदाज कर दिया जाता है set -e
। हालाँकि, अब यह एक फ़ंक्शन है, फ़ंक्शन का एक्ज़िट कोड उस कमांड के एग्ज़िट कोड के बराबर है, और नॉनज़ेरो लौटने वाला फ़ंक्शन चुपचाप स्क्रिप्ट को समाप्त कर देगा।
सेट
IFS = $ '\ n' रीड -d '' -r -a config_vars <config
ऊपर config_vars
फ़ाइल से सरणी को पढ़ा जाएगा config
। जैसा कि लेखक का इरादा हो सकता है, यह config
गायब होने पर एक त्रुटि के साथ समाप्त होता है। जैसा कि लेखक का इरादा नहीं हो सकता है, यह चुपचाप समाप्त हो जाता है अगर config
एक नई पंक्ति में समाप्त नहीं होता है। यदि set -e
यहां उपयोग नहीं किया गया था, तो config_vars
फ़ाइल की सभी लाइनें शामिल होंगी या नहीं यह एक नई पंक्ति में समाप्त हो गई है।
उदात्त पाठ के उपयोगकर्ता (और अन्य पाठ संपादक जो नए सिरे से गलत तरीके से संभालते हैं), सावधान रहें।
सेट
should_audit_user () {
स्थानीय समूह समूह = "$ (समूह" $ 1 ")"
$ समूहों में समूह के लिए; करना
अगर ["$ समूह" = ऑडिट]; फिर वापसी 0; फाई
किया हुआ
वापसी 1
}
अगर "$ उपयोगकर्ता" चाहिए फिर
लकड़हारा 'ब्लाह'
फाई
यहाँ लेखक यथोचित अपेक्षा कर सकता है कि यदि किसी कारण से उपयोगकर्ता $user
मौजूद नहीं है, तो groups
कमांड विफल हो जाएगी और उपयोगकर्ता को कुछ कार्य करने की अनुमति देने के बजाय स्क्रिप्ट समाप्त हो जाएगी। हालांकि, इस मामले में set -e
समाप्ति कभी भी प्रभावी नहीं होती है। यदि $user
किसी कारण से नहीं मिल रहा है, तो स्क्रिप्ट को समाप्त करने के बजाय, should_audit_user
फ़ंक्शन गलत डेटा लौटाएगा जैसे कि set -e
प्रभाव में नहीं था।
यह एक if
बयान के हालत भाग से आह्वान किए गए किसी भी फ़ंक्शन पर लागू होता है , चाहे कितना भी गहरा घोंसला क्यों न हो, इसे परिभाषित नहीं किया जाता है, भले ही आप set -e
इसे फिर से अंदर चलाते हों । if
किसी भी बिंदु पर उपयोग पूरी तरह से set -e
तब तक प्रभाव को निष्क्रिय कर देता है जब तक कि हालत ब्लॉक को पूरी तरह से निष्पादित नहीं किया जाता है। यदि लेखक को इस नुकसान के बारे में पता नहीं है, या सभी संभावित स्थितियों में उनके पूरे कॉल स्टैक को नहीं जानता है, जिसमें कोई फ़ंक्शन कहा जा सकता है, तो वे छोटी गाड़ी कोड लिखेंगे और प्रदान की गई सुरक्षा की झूठी भावना set -e
कम से कम आंशिक रूप से होगी दोष।
भले ही लेखक इस नुकसान के बारे में पूरी तरह से अवगत हो, लेकिन वर्कअराउंड कोड को उसी तरह से लिखना है जैसे कोई इसे बिना लिखे set -e
, प्रभावी रूप से उस स्विच को बेकार से कम प्रदान करता है; न केवल लेखक को मैनुअल एरर हैंडलिंग कोड लिखना set -e
पड़ता है, जैसा कि प्रभाव में नहीं था, लेकिन set -e
हो सकता है कि उपस्थिति ने उन्हें यह सोचकर बेवकूफ बनाया हो कि उन्हें नहीं करना है।
कुछ और कमियां set -e
:
- यह मैला कोड को प्रोत्साहित करता है। त्रुटि हैंडलर के बारे में पूरी तरह से भूल गए हैं, इस उम्मीद में कि जो भी विफल हुआ वह त्रुटि को कुछ समझदार तरीके से रिपोर्ट करेगा। हालांकि,
let x++
ऊपर जैसे उदाहरणों के साथ , यह मामला नहीं है। यदि स्क्रिप्ट अप्रत्याशित रूप से मर जाती है, तो यह आमतौर पर चुपचाप होता है, जो डिबगिंग में बाधा उत्पन्न करता है। यदि स्क्रिप्ट नहीं मरती है और आप इसकी उम्मीद करते हैं (पिछली बुलेट बिंदु देखें), तो आपके हाथ में एक अधिक सूक्ष्म और कपटी बग है।
- यह लोगों को सुरक्षा की झूठी भावना में ले जाता है। फिर से देखें
if
-कंडिशन बुलेट बिंदु।
- जिन स्थानों पर शेल समाप्त होता है, वे शेल या शेल संस्करणों के बीच संगत नहीं होते हैं। गलती से एक स्क्रिप्ट लिखना संभव है,
set -e
जो उन संस्करणों के साथ जुड़ने के व्यवहार के कारण बैश के पुराने संस्करण पर अलग-अलग व्यवहार करता है ।
set -e
एक विवादास्पद मुद्दा है, और आसपास के मुद्दों से अवगत कुछ लोग इसके खिलाफ सलाह देते हैं, जबकि कुछ अन्य लोग केवल सावधानी बरतने की सलाह देते हैं जबकि यह नुकसान जानने के लिए सक्रिय है। ऐसे कई शेल स्क्रिप्टिंग वाले न्यूबाय हैं, जो set -e
सभी स्क्रिप्ट्स को कैच-ऑल के रूप में त्रुटि की स्थिति के लिए सुझाते हैं, लेकिन वास्तविक जीवन में यह उस तरह से काम नहीं करता है।
set -e
शिक्षा का कोई विकल्प नहीं है।