क्यों पैटर्न है "कमांड || सच ”उपयोगी?


78

मैं वर्तमान में डेबियन पैकेज तलाश रहा हूं, और मैं कुछ कोड नमूने पढ़ रहा हूं। और हर पंक्ति में, उदाहरण के लिए, postinstस्क्रिप्ट एक पैटर्न है।

some command || true
another command || true

इसलिए यदि कुछ कमांड विफल हो जाती है, तो लाइन सही हो जाती है, लेकिन मैं यह नहीं देखता कि यह प्रोग्राम के आउटपुट को कैसे प्रभावित करता है।


5
FYI करें, ||:यह लिखने का एक और मुहावरेदार तरीका है - (यह :एक और प्रविष्टि है, जो बाॅडीइन की ओर इशारा करते हुए बनाया गया है true- लेकिन वापस बॉर्न के लिए भी एक बिलियन होने की गारंटी दी गई है;) उन्होंने कहा, POSIX श के लिए, trueइसी तरह एक बिलिन होने की गारंटी है - तो यह है सम-दूरस्थ-आधुनिक समय में दक्षता की तुलना में अधिक मरोड़)।
चार्ल्स डफी

जवाबों:


151

इस पैटर्न का कारण यह है कि डेबियन संकुल में अनुरक्षक स्क्रिप्ट के साथ शुरू होता है set -e, जो शेल को बाहर निकलने का कारण बनता है जैसे ही कोई भी कमांड (सख्ती से बोलना, पाइपलाइन, सूची या मिश्रित कमांड) एक गैर-शून्य स्थिति के साथ बाहर निकलता है। यह सुनिश्चित करता है कि त्रुटियाँ जमा न हों: जैसे ही कुछ गलत होता है, स्क्रिप्ट निरस्त हो जाती है।

ऐसे मामलों में जहां स्क्रिप्ट में एक कमांड को विफल करने की अनुमति दी जाती है, जोड़ना || trueयह सुनिश्चित करता है कि परिणामस्वरूप कंपाउंड कमांड हमेशा स्थिति शून्य के साथ बाहर निकलता है, इसलिए स्क्रिप्ट का उपयोग नहीं करता है। उदाहरण के लिए, एक निर्देशिका को हटाने से एक घातक त्रुटि नहीं होनी चाहिए (एक पैकेज को हटाने से रोका जा सकता है); इसलिए हम उपयोग करेंगे

rmdir ... || true

चूँकि rmdirइसमें त्रुटियों को अनदेखा करने का विकल्प नहीं है।


4
खैर, set -eइसके लिए कोई आवश्यकता नहीं है || true, मैंने संदर्भ प्रदान करना महत्वपूर्ण समझा। यदि आप POWER पर अजीब चीजें देखते हैं, तो मैं आपको बग्स ( reportbug) दर्ज करने के लिए दृढ़ता से प्रोत्साहित करता हूं !
स्टीफन किट

16
@MichaelFelt, वास्तव set -eमें न केवल "डेबियन सम्मेलन" है, लेकिन एक अच्छा प्रोग्रामिंग पैटर्न हमेशा उपयोग करना चाहिए। देख। उदा। davidpashley.com/articles/writing-robust-shell-scripts
kay

2
यहां प्रति प्रश्न के अनुसार - || trueसेट-ई का उपयोग क्यों किया जाना संभावित संदर्भ है और संभवतः सबसे आम है। मैं इस जवाब को नमन करता हूँ! वस्तुतः हालांकि, यह उपयोगी है कभी भी निकास की स्थिति को अप्रासंगिक माना जाता है और (जैसा कि आप लेख लिंक कहते हैं) मैं अपनी स्क्रिप्ट नियंत्रण के भाग के रूप में निकास स्थिति का उपयोग नहीं कर रहा हूं। मुझे उपयोगिता (में set -e) दिखाई देती है, लेकिन लेख के अनुसार ऐसा नहीं होता है और कहते हैं कि "आपके द्वारा लिखी गई प्रत्येक स्क्रिप्ट में सेट-टॉप शामिल होना चाहिए"। यह प्रोग्रामिंग की एक शैली है। "हमेशा | हर" इसमें जाल का एक सेट शामिल है - उर्फ ​​- निरपेक्ष पुन: वाइल्ड-कार्ड समाधान ALWAYSअंततः उर्फ ​​- कोई मुफ्त सवारी नहीं करेंगे ।
माइकल

1
@Kay यह वर्तमान में लोकप्रिय परिप्रेक्ष्य है लेकिन अंततः कई मान्यताओं के साथ मेल खाता है जो स्क्रिप्ट की पोर्टेबिलिटी को सीमित करता है। set -eव्यवहार के साथ ऐतिहासिक विसंगतियां हैं। यह आपके लिए महत्वपूर्ण नहीं हो सकता है, यदि आपके एकमात्र लक्ष्य हैं bashऔर अन्य अपेक्षाकृत हाल के गोले हैं जो कि रहते हैं /bin/sh, लेकिन जब आप पुराने गोले / सिस्टम का समर्थन करना चाहते हैं तो स्थिति अधिक बारीक होती है।
1925 में mtraceur

2
@StephenKitt ज़रूर। वहाँ एक बहुत ही गहन है विभिन्न गोले 'का दस्तावेजीकरण पेज set -eस्वेन Mascheck द्वारा व्यवहार हालांकि यह पेज भी अप्रासंगिक आज ऐतिहासिक / प्राचीन गोले का एक बहुत दस्तावेजों,। एक संकीर्ण आधुनिक फ़ोकस ("सेट-ई के लिए खोज") के साथ ये दो पृष्ठ भी हैं: "लिंटश" पृष्ठ , ऑटोकॉन्फ़ का पोर्टेबल शेल दस्तावेज़ीकरण -> बिल्ट उप पृष्ठ की सीमा
mtraceur

32

हालांकि यह केवल चलने वाले प्रोग्राम के आउटपुट को प्रभावित नहीं करता है - यह कॉलर को आगे बढ़ने की अनुमति देता है जैसे कि सब ठीक है उर्फ ​​भविष्य के तर्क को प्रभावित करता है।

Rephrased: यह पिछले कमांड के एरर स्टेटस को मास्क करता है ।

michael@x071:[/usr/sbin]cat /tmp/false.sh
#!/bin/sh
false

michael@x071:[/usr/sbin]cat /tmp/true.sh 
#!/bin/sh
false || true

michael@x071:[/usr/sbin]sh /tmp/false.sh; echo $?
1
michael@x071:[/usr/sbin]sh /tmp/true.sh; echo $? 
0

6
यह सच है, लेकिन यह जवाब नहीं देता है कि कमांड की निकास स्थिति को मास्क करना क्यों उपयोगी है।
मोपेट

4
सेट-ई का मतलब है कि स्क्रिप्ट तुरंत गैर-शून्य रिटर्न पर समाप्त हो जाएगी। आप उस स्थानीयकृत स्थान पर, ऐसा नहीं चाहते हैं!
रैकैंडबॉमनमैन

मैं एक साधारण व्यक्ति हूं - और मेरे लिए त्रुटि स्थिति को मुखौटा करने का एकमात्र कारण है क्योंकि यह "रास्ते में" है। set -e कोई भी त्रुटि करता है "अगर आप परवाह नहीं करते हैं तो" रास्ते में "। मुझे चर्चा पसंद है क्योंकि मैं इसे अपनी स्क्रिप्ट को डीबग करने में मदद करने के लिए एक अच्छा तरीका के रूप में देखता हूं और त्रुटि का जवाब देने के लिए अतिरिक्त तर्क लिखता हूं (उदाहरण के लिए, प्रिंट - "xxx यहां गैर-शून्य मौजूद है"। अधिक संभावना है, हालांकि मेरे पास एक है शेल फ़ंक्शन 'घातक' और मेरे पास "कुछ है" घातक "मुझे नाखुश करें"। एक स्क्रिप्ट को एक असफल स्थिति की रिपोर्ट करनी चाहिए, या देखभाल नहीं करनी चाहिए -e प्लस || सच्ची मास्किंग त्रुटियां हैं। यदि मैं यही चाहता हूं - ठीक है यदि नहीं, तो मुझे गलतियां याद आ रही हैं
माइकल फेल्ट

मुझे अपने आप से पूछना है: क्या है || सच - एक कोडिंग बैसाखी (लगभग एक त्रुटि पाने के लिए आलसी तरीका / एक त्रुटि जो मैं अब नहीं निपटना चाहता हूं; एक डिबग टूल (-ई लेकिन नहीं || सच) या बस किसी की हठधर्मिता के बारे में अच्छा व्यवहार क्या है। दूसरे शब्दों में - मैं इसे एक विशेषता के रूप में देखता हूं - संभावित लाभ के साथ। मैं इसे सभी को ठीक करने के लिए एक जादू की छड़ी के रूप में नहीं देखता हूं। संक्षेप में - जैसे सौंदर्य देखने वाले की आंखों में है - set -eऔर || trueउपयोगिता को लक्षणों और लक्ष्यों द्वारा परिभाषित किया जाएगा। प्रोग्रामर।
माइकल

6
@MichaelFelt गौर करें: git remote remove foo || true git remote add foo http://blah- यदि रिमोट मौजूद नहीं है, तो हम त्रुटि को अनदेखा करना चाहते हैं।
इमिबिज़िस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.