खानाबदोश के मामले में बाहर निकलने से रोकें


29

यह स्क्रिप्ट "के बाद" गूँजती नहीं है:

#!/bin/bash -e

echo "before"

echo "anything" | grep e # it would if I searched for 'y' instead

echo "after"
exit

यह भी होता अगर मैं -eशेलबैंग लाइन पर विकल्प को हटा देता , लेकिन मैं इसे रखना चाहता हूं, तो कोई त्रुटि होने पर मेरी स्क्रिप्ट बंद हो जाती है। मैं grep को बिना किसी त्रुटि के मैच के रूप में नहीं मानता। मैं इसे अचानक से बाहर निकलने से कैसे रोक सकता हूं?


यह एक अवलोकन है जो केवल विचार के लिए है। शायद इस लिपि के तर्क पर फिर से विचार किया जाए। यदि यह स्ट्रिंग खोजने के लिए महत्वपूर्ण नहीं है, तो इसके लिए क्यों खोजें? grep की परिभाषा ऐसी है जो किसी स्ट्रिंग की उपस्थिति या अनुपस्थिति के आधार पर निर्णय लेती है। यदि आप किसी भी तरह से परवाह नहीं करते हैं, तो यह महत्वपूर्ण नहीं है। इसके अलावा, यह प्रतीत होता -eहै कि आप देखभाल करते हैं: इतना कि कोई भी समस्या भयावह है।
एंड्रयू फलांगा

2
@AndrewFalanga मैं किसी भी तरह से देखभाल करता हूं क्योंकि मैं वास्तव में उस सामग्री का विश्लेषण कर रहा हूं var=$(complex command | grep complex_pattern)जो अशक्त हो सकती है (जिस स्थिति में मेरा कार्यक्रम समाप्त नहीं होना चाहिए)। यह केवल एक उबली हुई स्क्रिप्ट है जो समस्या को उत्पन्न करती है। यहाँ तर्क में कोई आध्यात्मिक ब्लैकहोल नहीं है, है ना? ;)
इगो-लिटो

अब यह जानकर कि आप आउटपुट पर कब्जा करना चाहते हैं, कुछ चीजों को स्पष्ट करता है। जैसा कि प्रस्तुत किया गया था, यह मुझे भ्रमित कर रहा था।
एंड्रयू फेलंगा

जवाबों:


33
echo "anything" | grep e || true

स्पष्टीकरण:

$ echo "anything" | grep e
### error
$ echo $?
1
$ echo "anything" | grep e || true
### no error
$ echo $?
0
### DopeGhoti's "no-op" version
### (Potentially avoids spawning a process, if `true` is not a builtin):
$ echo "anything" | grep e || :
### no error
$ echo $?
0

"" || का अर्थ है "या"। यदि कमांड का पहला भाग "विफल" होता है (जिसका अर्थ है "grep e" एक गैर-शून्य निकास कोड देता है) तो "" "भाग के बाद का भाग एक्ज़िट कोड के रूप में निष्पादित किया जाता है, सफल होता है और शून्य देता है ( trueहमेशा शून्य लौटता है)।


3
उसी का थोड़ा छोटा संस्करण जो स्पिन नहीं करता /bin/trueहै: command || :(तो आपके मामले में set -e; grep 'needle' haystack || :)।
डोपघोटी

1
@ डोपघोटी, trueकुछ बिल्ट में (कम से कम bash 4.3
आरएचईएल

3
मान्य नहीं है क्योंकि यदि पहली कमांड विफल हो जाती है तो यह त्रुटि को छिपा देगा। यदि पाइप में पहला कमांड विफल रहता है, तो एक सही समाधान गैर शून्य वापस करना चाहिए।
सोरिन

11

सुरक्षित और वैकल्पिक grep संदेशों के लिए एक मजबूत तरीका :

echo something | grep e || [[ $? == 1 ]] ## print 'something', $? is 0
echo something | grep x || [[ $? == 1 ]] ## no output, $? is 0
echo something | grep --wrong-arg e || [[ $? == 1 ]] ## stderr output, $? is 1

पॉज़िक्स मैनुअल के अनुसार, एग्ज़िट कोड 1 का अर्थ है कोई रेखाएं नहीं चुनी गईं, और> 1 का अर्थ त्रुटि है।


1
यह स्वीकृत उत्तर होना चाहिए, क्योंकि यह केवल चेतावनी निकास कोड (1) को दबा देता है अगर grep को कुछ भी नहीं मिलता है, फिर भी यह सही त्रुटियों (निकास कोड> 1) पर गुजरता है। यहां अन्य समाधान हमेशा सही त्रुटियों को दबाते हैं, जो आमतौर पर खराब होता है।
हेरोल्डफिन

7

एक अन्य विकल्प पाइपलाइन में एक और कमांड जोड़ना है - एक जो विफल नहीं है:

echo "anything" | grep e | cat

क्योंकि catअब पाइपलाइन में अंतिम कमांड है, यह बाहर निकलने की स्थिति है cat, न grepकि, यह निर्धारित करने के लिए उपयोग किया जाएगा कि पाइप लाइन विफल हुई या नहीं।



3

समाधान

#!/bin/bash -e

echo "before"

echo "anything" | grep e || : # it would if I searched for 'y' instead

echo "after"
exit

व्याख्या

set -e या set -o errexit

यदि एक पाइपलाइन (जिसमें एक एकल साधारण कमांड शामिल हो सकती है ), एक सूची , या एक कंपाउंड कमांड ( SHELL GRAMMARऊपर देखें ), एक गैर-शून्य स्थिति से बाहर निकलता है। खोल से बाहर निकलें, तो आदेश है कि विफल रहता आदेश सूची का हिस्सा तुरंत एक निम्नलिखित है नहीं है whileया untilहै, तो निम्न परीक्षण का हिस्सा कीवर्ड ifया elifआरक्षित शब्द, एक में मार डाला किसी भी आदेश का हिस्सा &&या ||आदेश को छोड़कर इस सूची अंतिम निम्नलिखित &&या ||, किसी भी एक पाइप लाइन में कमांड लेकिन अंतिम, या यदि कमांड के रिटर्न वैल्यू के साथ उलटा किया जा रहा है!। यदि किसी सबडेल के अलावा अन्य कंपाउंड कमांड एक गैर-शून्य स्थिति देता है क्योंकि एक कमांड को विफल -eकर दिया जाता है जबकि अनदेखा किया जा रहा है, तो शेल बाहर नहीं निकलता है। एक जाल पर ERR, अगर सेट, खोल बाहर निकलने से पहले निष्पादित किया जाता है। यह विकल्प शेल पर्यावरण और प्रत्येक उप-शेल पर्यावरण पर अलग से ( COMMAND EXECUTION ENVIRONMENTऊपर देखें ) पर लागू होता है , और सब-कमांड में सब-कमांड को निष्पादित करने से पहले सबस्क्रिप्शन को बाहर निकलने का कारण हो सकता है।

प्लस, :बैश में नो-इफेक्ट कमांड है।

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