ईआरआर और एग्जिट जाल के साथ ( ) set -e
( errexit
) का उपयोग करते समय मैं कुछ अजीब व्यवहार देख रहा हूं । वे संबंधित प्रतीत होते हैं, इसलिए उन्हें एक प्रश्न में रखना उचित लगता है।set -u
nounset
1) set -u
ईआरआर ट्रैप को ट्रिगर नहीं करता है
कोड:
#!/bin/bash trap 'echo "ERR (rc: $?)"' ERR set -u echo ${UNSET_VAR}
- अपेक्षित: ERR जाल कहा जाता है, RC! = 0
- वास्तविक: ERR ट्रैप को नहीं कहा जाता है, RC == 1
- नोट:
set -e
परिणाम नहीं बदलता है
2) set -eu
एक EXIT ट्रैप में एग्जिट कोड का उपयोग 1 के बजाय 0 है
कोड:
#!/bin/bash trap 'echo "EXIT (rc: $?)"' EXIT set -eu echo ${UNSET_VAR}
- अपेक्षित: EXIT जाल कहा जाता है, RC == 1
- वास्तविक: EXIT जाल को कहा जाता है, RC == 0
- नोट: उपयोग करते समय
set +e
, RC == 1. EXIT ट्रैप उचित RC तब लौटाता है जब कोई अन्य कमांड एक एरर फेंकता है। - संपादित करें: एक दिलचस्प टिप्पणी के साथ इस विषय पर एक एसओ पोस्ट है जो सुझाव देता है कि यह बैश संस्करण से संबंधित हो सकता है। बैश 4.3.11 के साथ इस स्निपेट का परीक्षण एक RC = 1 में करता है, इसलिए यह बेहतर है। दुर्भाग्य से सभी मेजबानों पर बैश (3.2.51 से) को अपग्रेड करना फिलहाल संभव नहीं है, इसलिए हमें कुछ अन्य समाधान के साथ आना होगा।
किसी को भी इन व्यवहारों की व्याख्या कर सकते हैं?
इन विषयों की खोज करना बहुत सफल नहीं था, जो कि बश सेटिंग्स और ट्रैप्स पर पदों की संख्या को देखते हुए आश्चर्य की बात है। नहीं है एक मंच धागा है, हालांकि, लेकिन निष्कर्ष नहीं बल्कि नाकाफी है।
set -e
और set -u
दोनों को विशेष रूप से एक स्क्रिप्टेड शेल को मारने के लिए डिज़ाइन किया गया है । उन स्थितियों में उनका उपयोग करना जो उनके आवेदन को ट्रिगर कर सकते हैं एक स्क्रिप्टेड शेल को मार देंगे । उनके आसपास कोई ऐसा नहीं है, सिवाय उनके उपयोग के नहीं , और उन परिस्थितियों के लिए परीक्षण करने के लिए जब वे एक कोड अनुक्रम में लागू होते हैं। तो, मूल रूप से, आप अच्छे शेल-कोड लिख सकते हैं, या आप उपयोग कर सकते हैं set -eu
।
-u
पाई है कि ईआरआर ट्रैप को ट्रिगर क्यों नहीं किया जाएगा (यह एक त्रुटि है, इसलिए इसे ट्रैप को ट्रिगर नहीं करना चाहिए) या त्रुटि कोड 1 के बजाय 0 है। उत्तरार्द्ध एक बग हो सकता है जो बाद के संस्करण में पहले से ही तय हो गया है, इसलिए ऐसा है। लेकिन पहला भाग यह समझने में काफी कठिन है कि क्या आपको एहसास नहीं हुआ है कि शेल मूल्यांकन में त्रुटि (पैरामीटर विस्तार) और कमांड में वास्तविक त्रुटियां अलग-अलग चीजें हैं। समाधान के लिए, ठीक है, जैसा कि आपने सुझाव दिया था, मैं अब -eu
आवश्यक होने पर मैन्युअल रूप से बचने और जांचने की कोशिश कर रहा हूं ।
(set -u; : $UNSET_VAR)
और इसी तरह। इस तरह का सामान अच्छा भी हो सकता है - आप &&
कभी-कभार गिर सकते हैं : (set -e; mkdir dir; cd dir; touch dirfile)
यदि आपको मेरा बहाव मिलता है। यह सिर्फ इतना है कि वे नियंत्रित संदर्भ हैं - जब आप उन्हें वैश्विक विकल्पों के रूप में सेट करते हैं, तो आप नियंत्रण खो देते हैं और नियंत्रित हो जाते हैं। आमतौर पर अधिक कुशल समाधान होते हैं, हालांकि।
bash
मानक के साथ टूट गया और उपधाराओं में जाल डालना शुरू कर दिया। माना जाता है कि जाल उसी वातावरण में निष्पादित किया जाता है, जहां से वापसी हुई थी, लेकिनbash
काफी समय तक ऐसा नहीं किया।