"सेट -o संज्ञा" का उपयोग करते समय एक चर को bash में सेट किया गया है तो टेस्ट करें


95

निम्नलिखित कोड एक अनबाउंड चर त्रुटि के साथ बाहर निकलता है। set -oसंज्ञा विकल्प का उपयोग करते हुए भी इसे कैसे ठीक करें ?

#!/bin/bash

set -o nounset

if [ ! -z ${WHATEVER} ];
 then echo "yo"
fi

echo "whatever"

जवाबों:


98
#!/bin/bash

set -o nounset


VALUE=${WHATEVER:-}

if [ ! -z ${VALUE} ];
 then echo "yo"
fi

echo "whatever"

इस मामले में, VALUEयदि WHATEVERसेट नहीं किया जाता है तो एक खाली स्ट्रिंग समाप्त होता है। हम {parameter:-word}विस्तार का उपयोग कर रहे हैं , जिसे आप man bash"पैरामीटर विस्तार" के तहत देख सकते हैं ।


14
बस की जगह अगर [! -z $ {VALUE}]; अगर [के साथ! -z $ {WHATEVER: -}];
एंजेलम ऑक्ट

18
:-जाँचता है कि क्या चर अशांत है या खाली है। यदि आप केवल यह देखना चाहते हैं कि क्या यह परेशान है, तो उपयोग -करें VALUE=${WHATEVER-}:। इसके अलावा, यह जाँचने के लिए अधिक पठनीय तरीका है कि एक चर खाली है:if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
l0b0

1
इसके अलावा, यह काम नहीं करेगा यदि $WHATEVERकेवल व्हाट्सएप हो - मेरा उत्तर देखें।
l0b0

9
क्या ! -zसिर्फ " -n" के बजाय " " का उपयोग करने का कोई कारण है ?
जोनाथन हार्टले

31

यदि आप अपेक्षित परिणाम प्राप्त करना चाहते हैं तो आपको चर को उद्धृत करने की आवश्यकता है:

check() {
    if [ -n "${WHATEVER-}" ]
    then
        echo 'not empty'
    elif [ "${WHATEVER+defined}" = defined ]
    then
        echo 'empty but defined'
    else
        echo 'unset'
    fi
}

परीक्षा:

$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER='   '
$ check
not empty

मैं इस कोशिश की और मैं हैरान हूँ इस काम करता है ... सब कुछ छोड़कर के अनुसार सही है "info bash", "${WHATEVER-}"एक होना चाहिए ":"से पहले (कोलन) "-": (पानी का छींटा) की तरह "${WHATEVER:-}"है, और "${WHATEVER+defined}"इससे पहले कि एक कॉलन होना चाहिए "+"की तरह (धन): "${WHATEVER:+defined}"। मेरे लिए, यह बृहदान्त्र के साथ या उसके बिना भी काम करता है। 'निक्स के कुछ संस्करणों पर यह संभवत: बृहदान्त्र को शामिल किए बिना काम नहीं करेगा, इसलिए इसे संभवतः जोड़ा जाना चाहिए।
केविन फेगन

8
नहीं, -, +, :+, और :-सभी समर्थित हैं। पूर्व का पता चलता है कि क्या चर सेट है , और बाद वाला पता लगाता है कि यह सेट है या खाली है । से man bash: "केवल एक पैरामीटर के लिए एक परीक्षण में बृहदान्त्र परिणामों को स्वीकार करना जो परेशान है।"
l0b0

1
कोई बात नहीं =)। तुम सही हो। मुझे नहीं पता कि मैं कैसे चूक गया।
केविन फेगन

से डॉक्स : एक और तरीका है, तो पेट के शामिल किया गया है दोनों पैरामीटर के अस्तित्व के लिए और कहा कि अपने मूल्य रिक्त नहीं है ऑपरेटर परीक्षण रखो,,, यदि बृहदान्त्र को छोड़ दिया जाता है, तो ऑपरेटर केवल अस्तित्व के लिए परीक्षण करता है।
एक्यूमेनस

8

कैसे एक oneliner के बारे में?

[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"

-z खाली या परेशान चर दोनों के लिए जाँच करता है


2
नहीं, -zकेवल जाँचता है कि अगला पैरामीटर खाली है या नहीं। -zयह केवल [आदेश का एक तर्क है । परिवर्तनशील विस्तार [ -zकुछ भी करने से पहले होता है।
डोलमेन

1
यह सही समाधान की तरह लगता है, इसमें $ VAR सेट नहीं होने पर यह एक त्रुटि उत्पन्न नहीं करता है। @ डॉल्मेन क्या आप इसका उदाहरण दे सकते हैं कि यह कब काम नहीं करेगा?
क्रिस स्ट्राइकसिनस्की

@ डोलमेन ने परम विस्तार के बारे में विभिन्न बाश संसाधनों को पढ़ा है और अन्य उत्तरों को अधिक जटिल पाया है, मुझे इसमें कुछ भी गलत नहीं दिखता है। इसलिए आपका "स्पष्टीकरण", जबकि तकनीकी रूप से सही है, व्यवहार में व्यर्थ लगता है, जब तक आपको खाली बनाम बनाम अंतर करने की आवश्यकता नहीं है। मैंने अनसेट, खाली और नॉन-खाली, (बैश 4) का परीक्षण किया और यह बहुत अच्छा हुआ कि हर बार विज्ञापन दिया।
JL Peyret

8

मान्यताओं:

$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset

यदि आप एक गैर-संवादात्मक स्क्रिप्ट चाहते हैं, तो एक त्रुटि को मुद्रित करना और बाहर निकलना अगर कोई चर शून्य है या सेट नहीं है:

$ [[ "${HOME:?}" ]]

$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set

$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set

यदि आप स्क्रिप्ट से बाहर नहीं निकलना चाहते हैं:

$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."

$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.

$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.

आप उपयोग कर सकते हैं [और ]इसके बजाय [[और ]]ऊपर, लेकिन बाद को बैश में बेहतर है।

ध्यान दें कि उपनिवेश ऊपर क्या करता है। से डॉक्स :

एक और तरीका रखो, यदि बृहदान्त्र को शामिल किया जाता है, तो ऑपरेटर दोनों पैरामर के अस्तित्व के लिए परीक्षण करता है और इसका मूल्य शून्य नहीं है; यदि कोलन छोड़ा जाता है, तो ऑपरेटर केवल अस्तित्व के लिए परीक्षण करता है।

वहाँ स्पष्ट रूप से -nया के लिए कोई ज़रूरत नहीं है -z

सारांश में, मैं आमतौर पर सिर्फ उपयोग कर सकता हूं [[ "${VAR:?}" ]]उदाहरणों के अनुसार, यह एक त्रुटि प्रिंट करता है और बाहर निकलता है अगर एक चर शून्य है या सेट नहीं है।


4

आप उपयोग कर सकते हैं

if [[ ${WHATEVER:+$WHATEVER} ]]; then

परंतु

if [[ "${WHATEVER:+isset}" == "isset" ]]; then

अधिक पठनीय हो सकता है।


स्ट्रिंग तुलनाओं को मानक (POSIX) का उपयोग करना चाहिए = ऑपरेटर का , ==पोर्टेबिलिटी में सहायता करने के लिए नहीं और यदि संभव हो तो [इसके बजाय [[
जेन्स

2
@ प्रश्न प्रश्न को मारना और शामिल करना विशिष्ट है set -o nounset है। यदि आप #!/bin/bashअपनी स्क्रिप्ट के शीर्ष पर रखते हैं, तो वास्तव में बैश के संवर्द्धन का उपयोग करना सबसे अच्छा है।
बजे ब्रूनो ब्रोंस्की

0

हालांकि यह बिल्कुल ऊपर के लिए उपयोग किया गया मामला नहीं है , मैंने पाया है कि यदि आप उपयोग करना चाहते हैं nounset(या -u) डिफ़ॉल्ट व्यवहार वह है जो आप चाहते हैं: एक वर्णनात्मक संदेश के साथ नॉनज़रो से बाहर निकलने के लिए।

मुझे यह महसूस करने में काफी समय लगा कि मुझे लगा कि यह एक समाधान के रूप में पोस्ट करने लायक है।

यदि आप चाहते हैं कि बाहर निकलने पर कुछ और गूंज जाए, या कुछ सफाई करें, तो आप एक जाल का उपयोग कर सकते हैं।

:-ऑपरेटर संभव है कि आप अन्यथा चाहते हैं।

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