शेल स्क्रिप्ट में बूलियन मान का प्रतिनिधित्व करने के लिए सबसे अच्छा अभ्यास क्या है?


15

मुझे पता है, कि बूलियन मूल्य हैं bash, लेकिन मैं कभी भी उन्हें कहीं भी इस्तेमाल नहीं करते।

मैं अपनी मशीन पर अक्सर देखी जाने वाली जानकारी के लिए एक आवरण लिखना चाहता हूं, उदाहरण के लिए, यह विशेष रूप से यूएसबी ड्राइव डाला / घुड़सवार है।

इसे प्राप्त करने के लिए सबसे अच्छा अभ्यास क्या होगा?

  • एक स्ट्रिंग?

    drive_xyz_available=true
  • एक संख्या (सच के लिए 0, झूठी के लिए true 0)?

    drive_xyz_available=0    # evaluates to true
  • एक समारोह?

    drive_xyz_available() { 
        if available_magic; then 
                return 0 
        else 
                return 1 
        fi
    }

मैं ज्यादातर इस बारे में सोचता हूं कि अन्य लोगों द्वारा क्या उम्मीद की जाएगी जो रैपर का उपयोग करना चाहते हैं। क्या वे बूलियन मान, वैरिएबल जैसी कमांड या कॉल करने के लिए फ़ंक्शन की अपेक्षा करेंगे?

एक सुरक्षा दृष्टिकोण से मुझे लगता है कि दूसरा विकल्प सबसे सुरक्षित होगा, लेकिन मुझे आपके अनुभव सुनना अच्छा लगेगा।


3
help true ; help false ; help exit
कोस्टास

3
@ कोस्टस क्या आप विस्तृत विचार करेंगे?
मिनिक्स

जवाबों:


2
bool(){ return "$((!${#1}))"; }

if bool "$var"
then : do true
else : do false

बस कुछ भी करने के लिए एक चर सेट करें, लेकिन उपरोक्त के लिए काम करने के लिए शून्य नहीं, हालांकि [ -n "$var" ]कम होगा, यदि स्पष्ट नहीं है।

सामान्य तौर पर जब कोई स्क्रिप्ट एक पर्यावरण चर की व्याख्या या तो सही या गलत करती है, तो यह किसी भी मूल्य को सही होने के लिए व्याख्या करेगा (और कभी-कभी किसी विकल्प को कॉन्फ़िगर करने के लिए कहा गया मूल्य का उपयोग करें) या अन्यथा एक शून्य मान को गलत मानें।

उपरोक्त !notअपने पहले तर्क के लेन के बूलियन मूल्य को लौटाता है - यदि तर्क में 0 के अलावा किसी भी वर्ण के नंबर हैं, तो यह 0 है, अन्यथा, यदि कोई वर्ण बिल्कुल नहीं है, तो यह 1 लौटता है। यह वही परीक्षण है जिसे आप [ -n "$var" ]मूल रूप से कर सकते हैं , लेकिन यह सिर्फ नाम के एक छोटे से फ़ंक्शन में लपेटता है bool()

यह आमतौर पर एक ध्वज चर कैसे काम करता है। उदाहरण के लिए:

[ -d "$dir" ] || dir=

जहां किसी पटकथा के अन्य भागों को $dirअपनी उपयोगिता का अनुमान लगाने के लिए केवल किसी भी मूल्य की आवश्यकता होती है। यह भी काम आता है जहां पैरामीटर प्रतिस्थापन का संबंध है - क्योंकि पैरामीटर को खाली या परेशान लोगों के लिए भरने के लिए डिफ़ॉल्ट मानों तक विस्तारित किया जा सकता है, लेकिन अन्यथा प्रीसेट मान में विस्तार होगा ...

for set in yes ''
do echo "${set:-unset or null}"
done

... जो छपेगा ...

yes
unset or null

बेशक, इसके विपरीत करना भी संभव है, :+लेकिन यह कभी भी आपको केवल एक पूर्व निर्धारित डिफ़ॉल्ट या कुछ भी नहीं दे सकता है, जबकि उपरोक्त फॉर्म आपको एक मान या एक डिफ़ॉल्ट मान दे सकता है।

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


1
मुझे नहीं लगता कि आप मेरे सवाल का जवाब दे रहे हैं। मैं यह नहीं पूछ रहा हूं कि शेल स्क्रिप्ट में बूलियन का उपयोग कैसे किया जा सकता है, लेकिन क्या तरीका सबसे आम है और किसी अन्य उपयोगकर्ता द्वारा इसकी उम्मीद की जाएगी। यदि मेरा प्रश्न स्पष्ट नहीं है तो मुझे इसे संपादित करने में खुशी होगी। आपके उत्तर के लिए एक छोटा स्पष्टीकरण भी अच्छा होगा। धन्यवाद।
Minix

@Minix कोई बेहतर?
mikeserv

मैं आम तौर पर असाइन करता हूं trueया falseएक चर के लिए, आप तब कर सकते हैंif $variable; then ...
मिटा दें

@wurtel - जो कि डिफ़ॉल्ट पर निर्भर करता है $IFS- और यदि var के मान में किसी भी प्रकार का उपयोगकर्ता इनपुट हो सकता है, तो भी सरासर सौभाग्य पर। यदि मूल्य के साथ शुरू करने के लिए अज्ञात नहीं है, तो इसे परीक्षण करने की बहुत कम आवश्यकता है। अधिक सुरक्षित रूप से आप if ${var:+":"} false; thenकाम कर सकते हैं जब w / बूलियन नल / शून्य मान नहीं। लेकिन वह शायद ही कभी से अधिक उपयोगी है[ -n "$var" ] &&
mikeserv

यदि मैं अपनी स्क्रिप्ट के साथ शुरू करता हूं variable=falseऔर फिर इसे किसी भी स्थिति के अनुसार सही पर सेट करता हूं (जैसे मैं सी में एक चर का उपयोग करते समय) तो फिर कोई समस्या नहीं है, फिर भी अलग-अलग आईएफएस मूल्यों और यादृच्छिक चर मूल्यों आदि के साथ आपका जुनून क्या है .. ।
बड़बड़ाया

4

में bashहर चर अनिवार्य रूप से एक स्ट्रिंग (या किसी सरणी या एक समारोह है, लेकिन नियमित रूप से चर के बारे में यहाँ आइए बात करते हैं) है।

परीक्षण आदेशों के रिटर्न मूल्यों के आधार पर स्थितियों को पार्स किया जाता है - रिटर्न वैल्यू एक चर नहीं है, यह एक निकास स्थिति है। जब आप का मूल्यांकन if [ ... ]या if [[ ]]या if grep somethingया ऐसा कुछ, वापसी मान 0 (नहीं स्ट्रिंग 0, लेकिन बाहर निकलने स्थिति 0 = सफलता) सच और बाकी मतलब झूठी (जिसका अर्थ हां, तो क्या आप संकलित प्रोग्रामिंग भाषाओं में करने के लिए उपयोग किया जाता है से बिल्कुल विपरीत, लेकिन क्योंकि सफल होने का एक तरीका और विफल होने के कई तरीके हैं, और निष्पादन का अपेक्षित परिणाम आमतौर पर सफलता है, 0 का उपयोग सबसे आम डिफ़ॉल्ट परिणाम के रूप में किया जाता है यदि कुछ भी गलत नहीं होता है)। यह बहुत उपयोगी है क्योंकि किसी भी बाइनरी को परीक्षण के रूप में इस्तेमाल किया जा सकता है - अगर यह विफल हो जाता है, तो यह गलत है, अन्यथा यह सच है।

trueऔर falseप्रोग्राम (आमतौर पर बिल्डिंस द्वारा ओवरराइड) केवल उपयोगी छोटे प्रोग्राम हैं जो कुछ भी नहीं करते हैं - कुछ भी करने में trueसफल नहीं होता है, और 0 के साथ बाहर निकलता है, जबकि falseकुछ भी करने की कोशिश नहीं करता है और "विफल" होता है, 1 के साथ बाहर निकलता है । लगता है, लेकिन यह स्क्रिप्टिंग के लिए बहुत उपयोगी है।

के रूप में कैसे चारों ओर से सत्यता पारित करने के लिए, यह आप पर निर्भर है। यह सत्य और उपयोग के लिए सिर्फ "y" या "हां" का उपयोग करने के लिए काफी सामान्य है if [ x"$variable" = x"yes" ](डमी स्ट्रिंग को जोड़ दिया xक्योंकि यदि $variableशून्य लंबाई होती है, तो यह एक फर्जी कमांड बनाने से बचाता है if [ = "yes" ]जो पार्स नहीं करता है)। यह केवल झूठे के लिए एक खाली स्ट्रिंग का उपयोग करने के लिए उपयोगी हो सकता है, और [ -z "$variable ]यह परीक्षण करने के लिए उपयोग कर सकता है कि क्या यह शून्य-लंबाई है (या -nइसके लिए गैर-अक्षीय होना है)।

वैसे भी, यह वास्तव में बूलियन मूल्यों के आसपास से गुजरने के लिए काफी दुर्लभ है bash- यह बस exitविफलता पर बहुत अधिक सामान्य है , या एक उपयोगी परिणाम लौटाता है (या शून्य अगर कुछ गलत हो जाता है, और खाली स्ट्रिंग के लिए परीक्षण), और अधिकांश मामलों में कर सकते हैं एग्जिट स्टेटस से सीधे फेल होने का टेस्ट।


आपके मामले में, आप एक ऐसा फ़ंक्शन चाहते हैं जो किसी अन्य कमांड के रूप में कार्य करेगा (इसलिए, सफलता पर 0 लौटाएं), इसलिए आपका अंतिम विकल्प सही विकल्प लगता है।

साथ ही, आपको returnकथन की आवश्यकता भी नहीं हो सकती है । यदि फ़ंक्शन पर्याप्त सरल है, तो आप इस तथ्य का उपयोग कर सकते हैं कि यह फ़ंक्शन में अंतिम निष्पादित कमांड की स्थिति देता है। तो आपका कार्य बस हो सकता है

drive_xyz_available() {
   [ -e /dev/disk/by-uuid/whatever ]
}

यदि आप डिवाइस नोड के अस्तित्व के लिए परीक्षण कर रहे हैं (या /proc/mountsयह जांचने के लिए कि क्या यह माउंट है?)।


यह एक बहुत अच्छा सारांश है, इसे लिखने के लिए समय निकालने के लिए धन्यवाद। क्या मैं आपके अंतिम पैराग्राफ से अनुमान लगा सकता हूं कि आप drive_xyz_available()सबसे आम होने के विकल्प पर विचार करेंगे ?
Minix

क्या आप सामान्य y = trueमामले के लिए कुछ उदाहरण प्रदान कर सकते हैं ? मेरे अनुभव में, किसी भी शून्य मान के लिए अधिकांश आवरण लिपियों का परीक्षण इसे सही मानने के लिए करता है - कम से कम जहां व्याख्या किए गए पर्यावरण चर संबंधित हैं। अन्यथा वे शेल कारों को पूरी तरह से नजरअंदाज कर देते हैं।
mikeserv

3
ifयदि चर को उद्धृत किया जाता है, तो परीक्षण के लिए डमी स्ट्रिंग आवश्यक नहीं है; if [ "$variable" = "yes" ]$ चर सेट नहीं होने पर भी ठीक काम करता है।
डेनियल कुल्मन

-2

मूल रूप से कोई भी संख्या जो 0 नहीं है वह सत्य है, और 0 गलत है। विभिन्न प्रकार की त्रुटियों की पहचान करने के लिए स्क्रिप्ट या किसी अन्य संख्या के सफल समापन के लिए मानों को वापस करने का कारण।

$? पिछली कमांड / एक्जस्टेबल का एग्जिट कोड, 0 सक्सेस और किसी भी अन्य नंबर पर लौटाया गया त्रुटि है।

तो मैं उस विधि का सही / गलत उपयोग करूँगा। if (( ! $? ));then OK;else NOOK;fi


मैं अंतिम विकल्प के लिए एक लिखूंगा। धन्यवाद।
मिनिक्स

5
एक गैर-संख्या संख्या वास्तव में गलत है, और शून्य सच है। बस के उत्पादन को देखो true; echo $?और false; echo $?
रुस्लान

@Ruslan। क्या आपने मेरी कमांड का आउटपुट चेक किया? मुझे लगता है कि आपने नहीं किया, अन्यथा आपने यह नहीं कहा होता कि आपने क्या किया। 0 गलत है, कोई भी अन्य संख्या सही है, इसके !परिणाम को नकारने का कारण TRUE है। एक कमांड से परिणाम 0 है जब यह सही ढंग से समाप्त हो गया है, जिसका मतलब यह नहीं है कि 0 सच है। शब्द true0 हो सकता है, लेकिन 0 कभी भी सच नहीं है क्योंकि ifस्थिति प्रदर्शित करती है।
योस्मोस

यह कहते हुए कि C / C ++ में 0ऐसा trueही है , क्योंकि if(!x){True();}else{False();}कॉल True()कब होगी x==0। लेकिन सही जाँच नहीं !x, बल्कि होगी !!x
रुस्लान

आप गलत हैं। मैं इस बारे में बात नहीं कर रहा हूं कि आपके पास जो कुछ भी है, उसे लिखने के बाद ifमैं सिर्फ इस तथ्य को बताता हूं कि यहां (bash, या ksh, या tsh, या ....) के रूप में C / C ++ a 0 में FALSE है, कोई भी अन्य संख्या TRUE है, जैसा कि आप इस लिंक में पढ़ सकते हैं, C के प्रारंभिक कार्यान्वयन ने कोई बूलियन प्रकार प्रदान नहीं किया है, जो कि उन इन्टल्स के रूप में परिभाषित किया जा रहा है जहाँ 0 FALSE और 1 TRUE en.wikipedia.org/wiki/Bool__ata_type है
YoMismo
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.