अगर बैश में वैरिएबल सेट किया गया है तो कैसे जांचें?


1566

मुझे कैसे पता चलेगा कि बैश में एक चर सेट है?

उदाहरण के लिए, यदि उपयोगकर्ता किसी फ़ंक्शन को पहला पैरामीटर देता है, तो मैं कैसे जांच सकता हूं?

function a {
    # if $1 is set ?
}

12
if test $# -gt 0; then printf 'arg <%s>\n' "$@"; fi
जेन्स

210
समाधान-चाहने वालों पर ध्यान दें: इस सवाल के कई उच्च-श्रेणी के उत्तर हैं जो इस सवाल का जवाब देते हैं कि "चर गैर-रिक्त है"। अधिक सुधार समाधान ("चर सेट है") नीचे जेन्स और लियोनेल द्वारा जवाब में उल्लेख किया गया है।
नाथन किड

8
इसके अलावा रसेल हार्मन और सीमस अपने -vपरीक्षण के साथ सही हैं , हालांकि यह केवल bashशेल के पार पोर्टेबल और नहीं बल्कि नए संस्करणों पर उपलब्ध है ।
ग्रीम

5
जैसा कि @NathanKidd द्वारा बताया गया है, लियोनेल और जेन्स द्वारा सही समाधान दिए गए हैं। मुकदमा, आपको इनमें से किसी एक को अपना स्वीकृत जवाब देना चाहिए ।
गैरेट

3
... या गलत उत्तर को हमारे बीच अधिक समझदारी से कम किया जा सकता है, क्योंकि @prosseek समस्या को संबोधित नहीं कर रहा है।
दिन ३

जवाबों:


2299

(आमतौर पर) सही तरीका

if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi

जहां ${var+x}एक पैरामीटर विस्तार है जो कुछ भी नहीं होने पर मूल्यांकन करता है varऔर स्ट्रिंग को स्थानापन्न करता xहै।

उद्धरण पाचन

उद्धरण छोड़ा जा सकता है (इसलिए हम ${var+x}इसके बजाय कह सकते हैं "${var+x}") क्योंकि यह सिंटैक्स और उपयोग गारंटी देता है यह केवल उस चीज़ का विस्तार करेगा जिसमें उद्धरण की आवश्यकता नहीं है (क्योंकि यह या तो फैलता है x(जिसमें कोई शब्द नहीं टूटता है इसलिए इसे उद्धरण की आवश्यकता नहीं है), या प्राप्त करने के लिए कुछ नहीं (जिसके परिणामस्वरूप [ -z ], जो आसानी से उसी मूल्य का मूल्यांकन [ -z "" ]करता है (सच) जो भी करता है))।

हालांकि, जबकि उद्धरण सुरक्षित रूप से छोड़ा जा सकता है, और यह सभी के लिए तुरंत स्पष्ट नहीं था (यह इस उद्धरण स्पष्टीकरण के पहले लेखक के लिए भी स्पष्ट नहीं था, जो एक प्रमुख बैश कोडर भी है), कभी-कभी समाधान लिखना बेहतर होगा उद्धरण के साथ के रूप में[ -z "${var+x}" ] एक ओ (1) गति दंड की बहुत कम संभव लागत पर, । पहले लेखक ने इसे इस कोड का उपयोग करके कोड के बगल में एक टिप्पणी के रूप में जोड़ा, जो इस उत्तर को URL देता है, जिसमें अब यह स्पष्टीकरण भी शामिल है कि उद्धरण सुरक्षित रूप से क्यों छोड़ा जा सकता है।

(अक्सर) गलत तरीका

if [ -z "$var" ]; then echo "var is blank"; else echo "var is set to '$var'"; fi

यह अक्सर गलत होता है क्योंकि यह एक वैरिएबल के बीच अंतर नहीं करता है जो कि परेशान है और एक वैरिएबल जो खाली स्ट्रिंग पर सेट है। यह कहना है, अगरvar='' , तो उपरोक्त समाधान "var रिक्त है" आउटपुट होगा।

उन स्थितियों में जहां उपयोगकर्ता को एक्सटेंशन, या अतिरिक्त गुणों की सूची निर्दिष्ट करनी होती है, और जो उन्हें खाली स्ट्रिंग को निर्दिष्ट नहीं करना चाहिए, डिफॉल्ट को निर्दिष्ट नहीं करता है, उन स्थितियों में "सेट से खाली स्ट्रिंग" के बीच का अंतर आवश्यक है। स्क्रिप्ट को एक खाली एक्सटेंशन या अतिरिक्त गुणों की सूची का उपयोग करें।

भेद हालांकि हर परिदृश्य में आवश्यक नहीं हो सकता है। उन मामलों में [ -z "$var" ]बस ठीक हो जाएगा।


29
@ ग्रेट, आपके संपादन ने इस उत्तर को गलत बना दिया है, ${var+x}उपयोग करने के लिए सही प्रतिस्थापन है। का उपयोग करने से [ -z ${var:+x} ]कोई अलग परिणाम नहीं है [ -z "$var" ]
ग्रीम

11
यह काम नहीं करता है। मुझे "सेट" नहीं हो रहा है, भले ही यह मान किसी मान पर सेट हो या नहीं ("unset var" से साफ़ किया गया हो, "echo $ var" कोई आउटपुट नहीं देता)।
Brent212

10
समाधान के वाक्यविन्यास $ {पैरामीटर + शब्द} के लिए, आधिकारिक मैनुअल अनुभाग gnu.org/software/bash/manual/… है ; हालाँकि, उस में एक बग, यह बहुत स्पष्ट रूप से इस वाक्यविन्यास का उल्लेख नहीं करता है, लेकिन सिर्फ उद्धरण कहता है (बृहदान्त्र को छोड़ते हुए [":"] केवल एक पैरामीटर के लिए एक परीक्षण में परिणाम होता है जो परेशान है। .. $ {पैरामीटर: + शब्द}। [का अर्थ है] यदि पैरामीटर अशक्त या परेशान है, तो कुछ भी प्रतिस्थापित नहीं किया जाता है, अन्यथा शब्द का विस्तार प्रतिस्थापित किया जाता है); उद्धृत संदर्भ pubs.opengroup.org/onlinepubs/9699919799/utilities/… (अच्छा पता है) के यहाँ बहुत स्पष्ट डॉक्स हैं।
नियति वास्तुकार

7
ऐसा लगता है कि उद्धरण के लिए आवश्यक हैं जैसे जब आप एकाधिक एक्सप्रेशन का उपयोग कर, जैसे [ -z "" -a -z ${var+x} ]हो जाता है bash: [: argument expected-ubuntu 4.3 (लेकिन जैसे zsh) बैश में। मैं वास्तव में एक सिंटैक्स का उपयोग करके उत्तर को नापसंद करता हूं जो कुछ मामलों में काम करने के लिए होता है।
फॉक्सफॉक्स

41
एक सरल [ -z $var ]का उपयोग करना उद्धरणों को छोड़ने से अधिक "गलत" नहीं है। किसी भी तरह से, आप अपने इनपुट के बारे में धारणा बना रहे हैं। यदि आप एक खाली स्ट्रिंग को परेशान के रूप में ठीक कर रहे हैं, तो [ -z $var ]क्या आप सभी की आवश्यकता है।
nshew

909

गैर-शून्य / गैर-शून्य स्ट्रिंग चर के लिए जांच करने के लिए, अर्थात यदि सेट किया गया है, तो उपयोग करें

if [ -n "$1" ]

इसके विपरीत है -z। मैं खुद को -nज्यादा से ज्यादा इस्तेमाल कर पाता हूं-z

आप इसका उपयोग इस तरह करेंगे:

if [ -n "$1" ]; then
  echo "You supplied the first parameter!"
else
  echo "First parameter not supplied."
fi

86
मैं आमतौर पर [[ ]]अधिक पसंद करता हूं [ ], जैसा [[ ]]कि अधिक शक्तिशाली है और कुछ स्थितियों में कम समस्याओं का कारण बनता है ( दोनों के बीच अंतर की व्याख्या के लिए इस प्रश्न को देखें )। प्रश्न विशेष रूप से एक बैश समाधान के लिए पूछता है और किसी भी पोर्टेबिलिटी आवश्यकताओं का उल्लेख नहीं करता है।
प्रवाह करें

18
सवाल यह है कि कोई वैरिएबल सेट होने पर कैसे देख सकता है । तो फिर तुम कल्पना नहीं कर सकते कि चर रहा है निर्धारित किया है।
नमस्तेगौडबी

7
मैं सहमत हूं, []विशेष रूप से शेल (गैर-बैश) स्क्रिप्ट के लिए बेहतर काम करता है।
हेंजी

73
पर विफल रहता है set -u
सिरो सेंटिल्ली 冠状 i i i

63
ध्यान दें कि -nडिफ़ॉल्ट परीक्षा है, इसलिए अधिक सरलता से [ "$1" ]या [[ $1 ]]साथ ही काम करें। यह भी ध्यान दें कि [[ ]] उद्धृत करना अनावश्यक है
13:26

477

यहां पर परीक्षण किया जाता है कि क्या कोई पैरामीटर अशांत है , या खाली है ("नल") या मान के साथ सेट करें :

+--------------------+----------------------+-----------------+-----------------+
|   Expression       |       parameter      |     parameter   |    parameter    |
|   in script:       |   Set and Not Null   |   Set But Null  |      Unset      |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word}  | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word     | assign word     |
| ${parameter=word}  | substitute parameter | substitute null | assign word     |
| ${parameter:?word} | substitute parameter | error, exit     | error, exit     |
| ${parameter?word}  | substitute parameter | substitute null | error, exit     |
| ${parameter:+word} | substitute word      | substitute null | substitute null |
| ${parameter+word}  | substitute word      | substitute word | substitute null |
+--------------------+----------------------+-----------------+-----------------+

स्रोत: POSIX: पैरामीटर विस्तार :

"स्थानापन्न" के साथ दिखाए गए सभी मामलों में, अभिव्यक्ति को दिखाए गए मूल्य के साथ बदल दिया जाता है। "असाइन" के साथ दिखाए गए सभी मामलों में, पैरामीटर को उस मान को असाइन किया जाता है, जो अभिव्यक्ति को भी बदलता है।

कार्रवाई में यह दिखाने के लिए:

+--------------------+----------------------+-----------------+-----------------+
|   Expression       |  FOO="world"         |     FOO=""      |    unset FOO    |
|   in script:       |  (Set and Not Null)  |  (Set But Null) |     (Unset)     |
+--------------------+----------------------+-----------------+-----------------+
| ${FOO:-hello}      | world                | hello           | hello           |
| ${FOO-hello}       | world                | ""              | hello           |
| ${FOO:=hello}      | world                | FOO=hello       | FOO=hello       |
| ${FOO=hello}       | world                | ""              | FOO=hello       |
| ${FOO:?hello}      | world                | error, exit     | error, exit     |
| ${FOO?hello}       | world                | ""              | error, exit     |
| ${FOO:+hello}      | hello                | ""              | ""              |
| ${FOO+hello}       | hello                | hello           | ""              |
+--------------------+----------------------+-----------------+-----------------+

5
@HelloGoodbye हाँ यह काम करता है: इकोस set foo; echo ${1:-set but null or unset}"फू"; set --; echo ${1:-set but null or unset}गूँज सेट लेकिन अशक्त ...
Jens

4
@HelloGoodbye स्थितीय मापदंडों के साथ सेट किया जा सकता है, उह, set:-)
Jens

95
यह उत्तर बहुत भ्रामक है। इस तालिका का उपयोग करने के बारे में कोई व्यावहारिक उदाहरण?
बेन डेविस

12
@BenDavis विवरण POSIX मानक के लिंक में समझाया गया है, जो उस तालिका से लिया गया अध्याय का संदर्भ देता है। एक निर्माण : ${FOOBAR:=/etc/foobar.conf}जिसका उपयोग मैं लगभग किसी भी लिपि में लिखता हूं, यह एक चर के लिए एक डिफ़ॉल्ट मान सेट करना है यदि यह परेशान या अशक्त है।
जेन्स

1
parameterकिसी भी चर नाम है। wordतालिका में आप किस वाक्यविन्यास का उपयोग कर रहे हैं, और इस बात पर निर्भर करता है कि क्या चर $parameterका उपयोग किया जा सकता है, और क्या चर सेट है, लेकिन अशक्त है या परेशान है। चीजों को अधिक जटिल बनाने के लिए नहीं, बल्कि wordचर भी शामिल कर सकते हैं! एक चरित्र द्वारा अलग किए गए वैकल्पिक आर्ग्स को पारित करने के लिए यह बहुत उपयोगी हो सकता है। उदाहरण के लिए: ${parameter:+,${parameter}}आउटपुट एक अल्पविराम से अलग ,$parameterहो जाता है अगर यह सेट है, लेकिन अशक्त नहीं है। इस मामले में, wordहै,${parameter}
ट्रिनिट्रोनएक्स

260

जबकि यहां बताई गई अधिकांश तकनीकें सही हैं, बैश 4.2 वैरिएबल ( मैन बैश ) की उपस्थिति के लिए एक वास्तविक परीक्षण का समर्थन करता है , न कि वेरिएबल के मूल्य का परीक्षण करने के लिए।

[[ -v foo ]]; echo $?
# 1

foo=bar
[[ -v foo ]]; echo $?
# 0

foo=""
[[ -v foo ]]; echo $?
# 0

विशेष रूप से, यह दृष्टिकोण एक त्रुटि का कारण नहीं बनेगा, जब कई अन्य दृष्टिकोणों के विपरीत set -u/ set -o nounsetमोड में एक अनसेट वेरिएबल की जाँच के लिए उपयोग किया जाता है , जैसे कि उपयोग करना [ -z


9
बैश 4.1.2 में, इस बात की परवाह किए बिना कि क्या चर निर्धारित किया गया है, [[ -v aaa ]]; echo $?==>-bash: conditional binary operator expected -bash: syntax error near 'aaa'
दान

32
'टेस्ट' बिलिन में '-v' तर्क को बैश 4.2 में जोड़ा गया था।
टीआई स्ट्रगा

19
-v तर्क को -U शेल विकल्प (संज्ञा) के पूरक के रूप में जोड़ा गया था। 'संज्ञा' चालू (सेट -यू) के साथ, शेल एक त्रुटि लौटाएगा और समाप्त कर देगा, अगर यह इंटरैक्टिव नहीं है। $ # स्थितीय मापदंडों की जाँच के लिए अच्छा था। हालांकि, नामित चरों को क्लोबबेरिंग के अलावा किसी और तरीके की जरूरत थी, ताकि उन्हें परेशान किया जा सके। यह दुर्भाग्यपूर्ण है कि यह सुविधा इतनी देर से आई है क्योंकि कई लोग पहले वाले संस्करण के अनुकूल होने के लिए बाध्य हैं, इस स्थिति में वे इसका उपयोग नहीं कर सकते हैं। केवल एक अन्य विकल्प है कि ऊपर दिखाए गए अनुसार इसे प्राप्त करने के लिए ट्रिक्स या 'हैक्स' का उपयोग किया जाए लेकिन यह सबसे अयोग्य है।
ओसिरिसगोथरा

2
ध्यान दें कि यह उन चरों के लिए काम नहीं करता है जो घोषित किए गए हैं लेकिन परेशान नहीं हैं। जैसेdeclare -a foo
miken32

17
यही कारण है कि मैं स्वीकृत / उच्चतम मत वाले उत्तर के बाद भी पढ़ता रहता हूं।
जो

176

निम्नलिखित में से एक के साथ ऐसा करने के कई तरीके हैं:

if [ -z "$1" ]

यह सफल होता है यदि $ 1 अशक्त या परेशान है


46
अशक्त पैरामीटर और अशक्त मान वाले पैरामीटर के बीच अंतर होता है।
chepner

21
मैं सिर्फ पांडित्यपूर्ण होना चाहता हूं और यह कहना चाहता हूं कि सवाल क्या है इसका विपरीत उत्तर है। प्रश्न पूछते हैं कि क्या चर सेट है, यदि चर सेट नहीं है।
फिलुमिनाती

47
[[ ]]पोर्टेबिलिटी के नुकसान के अलावा कुछ नहीं है। if [ -n "$1" ]यहां इस्तेमाल किया जाना चाहिए।
जेन्स

73
यह उत्तर गलत है। प्रश्न यह बताने का तरीका पूछता है कि क्या एक चर निर्धारित किया गया है, न कि यह एक गैर-खाली मान पर सेट है। दिया गया है foo="", $fooएक मूल्य है, लेकिन -zकेवल रिपोर्ट करेगा कि यह खाली है। और -z $fooअगर आपके पास है तो फूंक देंगे set -o nounset
कीथ थॉम्पसन

4
यह "चर सेट है" की परिभाषा पर निर्भर करता है। यदि आप जाँचना चाहते हैं कि क्या चर शून्य-शून्य स्ट्रिंग पर सेट है , तो mbranning उत्तर सही है। लेकिन अगर आप यह जांचना चाहते हैं कि चर घोषित किया गया है लेकिन आरंभीकृत (यानी foo=) नहीं है, तो रसेल का उत्तर सही है।
प्रवाह

76

मुझे हमेशा POSIX तालिका दूसरे उत्तर में धीमी गति से टपकती हुई लगती है, इसलिए यहाँ मेरा इस पर लेना है:

   +----------------------+------------+-----------------------+-----------------------+
   |   if VARIABLE is:    |    set     |         empty         |        unset          |
   +----------------------+------------+-----------------------+-----------------------+
 - |  ${VARIABLE-default} | $VARIABLE  |          ""           |       "default"       |
 = |  ${VARIABLE=default} | $VARIABLE  |          ""           | $(VARIABLE="default") |
 ? |  ${VARIABLE?default} | $VARIABLE  |          ""           |       exit 127        |
 + |  ${VARIABLE+default} | "default"  |       "default"       |          ""           |
   +----------------------+------------+-----------------------+-----------------------+
:- | ${VARIABLE:-default} | $VARIABLE  |       "default"       |       "default"       |
:= | ${VARIABLE:=default} | $VARIABLE  | $(VARIABLE="default") | $(VARIABLE="default") |
:? | ${VARIABLE:?default} | $VARIABLE  |       exit 127        |       exit 127        |
:+ | ${VARIABLE:+default} | "default"  |          ""           |          ""           |
   +----------------------+------------+-----------------------+-----------------------+

ध्यान दें कि प्रत्येक समूह (पहले और बिना बृहदान्त्र के) में एक ही सेट और अनसेट मामले हैं, इसलिए केवल एक चीज अलग है कि खाली मामलों को कैसे संभाला जाता है।

पूर्ववर्ती बृहदान्त्र के साथ, खाली और परेशान मामले समान हैं, इसलिए मैं उन का उपयोग करूंगा जहां संभव हो (यानी उपयोग करें :=, न कि सिर्फ =इसलिए, क्योंकि खाली मामला असंगत है)।

शीर्षक:

  • सेट का मतलब VARIABLEगैर-खाली ( VARIABLE="something") है
  • खाली का मतलब VARIABLEहै खाली / अशक्त ( VARIABLE="")
  • परेशान का मतलब VARIABLEमौजूद नहीं है ( unset VARIABLE)

मान:

  • $VARIABLE इसका मतलब है कि परिणाम चर का मूल मूल्य है।
  • "default" इसका मतलब है कि प्रतिस्थापन स्ट्रिंग प्रदान की गई थी।
  • "" इसका मतलब है कि परिणाम शून्य है (एक रिक्त स्ट्रिंग)।
  • exit 127 इसका मतलब यह है कि स्क्रिप्ट एक्ज़िट कोड 127 के साथ निष्पादित होना बंद कर देती है।
  • $(VARIABLE="default")इसका मतलब है कि परिणाम चर का मूल मूल्य है और प्रदान की गई स्ट्रिंग को भविष्य के उपयोग के लिए चर को सौंपा गया है।

1
आपने बस वही निर्धारित किया है जो वास्तविक कोडिंग त्रुटियां हैं (चर के साथ काम करते समय अवांछित अप्रत्यक्षता के उदाहरण)। मैंने कुछ और मामलों को ठीक करने के लिए एक संपादन किया, जहां डॉलर विवरण की व्याख्या करने में फर्क करता है। BTW, सभी शेल चर (सरणियों के अपवाद के साथ) स्ट्रिंग चर हैं; यह सिर्फ ऐसा हो सकता है कि उनमें एक स्ट्रिंग हो जो एक संख्या के रूप में व्याख्या की जा सकती है। स्ट्रिंग्स के बारे में बात करना केवल संदेश को धूमिल करता है। उद्धरण का तार से कोई लेना-देना नहीं है, वे भागने का एक विकल्प हैं। VARIABLE=""के रूप में लिखा जा सकता है VARIABLE=। फिर भी, पूर्व अधिक पठनीय है।
पालेक

तालिका के लिए धन्यवाद यह बहुत उपयोगी है, हालांकि मैं स्क्रिप्ट से बाहर निकलने की कोशिश कर रहा हूं अगर कोई परेशान या खाली है। लेकिन मुझे जो एग्जिट कोड मिला है वह 1 नहीं 127 है।
अंतरिक्ष यात्री

64

यह देखने के लिए कि क्या कोई चर गैर-रिक्त है, मैं उपयोग करता हूं

if [[ $var ]]; then ...       # `$var' expands to a nonempty string

एक चर या तो अप्रयुक्त या खाली होने पर विपरीत परीक्षण:

if [[ ! $var ]]; then ...     # `$var' expands to the empty string (set or not)

यह देखने के लिए कि क्या एक चर (खाली या गैर-रिक्त) सेट है, मैं उपयोग करता हूं

if [[ ${var+x} ]]; then ...   # `var' exists (empty or nonempty)
if [[ ${1+x} ]]; then ...     # Parameter 1 exists (empty or nonempty)

एक चर अप्रभावित होने पर विपरीत परीक्षण:

if [[ ! ${var+x} ]]; then ... # `var' is not set at all
if [[ ! ${1+x} ]]; then ...   # We were called with no arguments

मैं भी कुछ समय से इसका उपयोग कर रहा हूं; बस एक कम तरीके से:[ $isMac ] && param="--enable-shared"

@ भास्कर मुझे लगता है कि यह उत्तर पहले से ही लगभग एक साल पहले अनिवार्य रूप से एक ही उत्तर ( iff सेट ${variable+x}करने के लिए उपयोग ) प्रदान किया गया था। इसके अलावा यह बहुत अधिक विस्तार से समझाता है कि यह सही क्यों है। x$variable
मार्क Haferkamp

लेकिन ${variable+x}कम पठनीय (और स्पष्ट) है
knocte

35

बैश के आधुनिक संस्करण पर (4.2 या बाद में मुझे लगता है; मुझे यकीन नहीं है), मैं यह कोशिश करूंगा:

if [ ! -v SOMEVARIABLE ] #note the lack of a $ sigil
then
    echo "Variable is unset"
elif [ -z "$SOMEVARIABLE" ]
then
    echo "Variable is set to an empty string"
else
    echo "Variable is set to some string"
fi

5
यह भी ध्यान दें कि [ -v "$VARNAME" ]गलत नहीं है, लेकिन बस एक अलग परीक्षण करता है। मान लीजिए VARNAME=foo; तब यह जाँचता है कि क्या कोई चर नाम fooहै जो सेट है।
चेपनर

5
पोर्टेबिलिटी चाहने वालों के लिए ध्यान दें, -vPOSIX
कंप्लेंट

यदि किसी को मिलता है [: -v: unexpected operator, तो bashइसके बजाय उपयोग करने के लिए सुनिश्चित करना होगा sh
कोपरपोर

25
if [ "$1" != "" ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

हालांकि तर्कों के लिए आम तौर पर $ # का परीक्षण करना सबसे अच्छा है, जो कि मेरी राय में, तर्कों की संख्या है।

if [ $# -gt 0 ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

1
पहला परीक्षण पिछड़ा हुआ है; मुझे लगता है कि आप चाहते हैं [ "$1" != "" ](या [ -n "$1" ]) ...
गॉर्डन डेविसन

10
यह $1रिक्त स्ट्रिंग पर सेट होने पर विफल हो जाएगा ।
हैलोगूडीबाई

2
उत्तर का दूसरा भाग (पैरामीटर की गणना) उत्तर के पहले भाग के लिए एक उपयोगी समाधान है जो काम नहीं करता है जब $1एक खाली स्ट्रिंग पर सेट किया जाता है।
मार्क बेरी

यदि set -o nounsetयह चालू है तो यह विफल हो जाएगा ।
फ्लिम

21

ध्यान दें

मैं bashटैग के कारण भारी बैश-केंद्रित उत्तर दे रहा हूं ।

संक्षिप्त जवाब

जब तक आप केवल बैश में नामांकित चर के साथ काम कर रहे हैं, तब तक यह फ़ंक्शन आपको हमेशा बताएगा कि क्या चर सेट किया गया है, भले ही वह खाली सरणी हो।

variable-is-set() {
    declare -p "$1" &>/dev/null
}

यह क्यों काम करता है

बैश में (कम से कम 3.0 के रूप में वापस), अगर varएक घोषित / सेट चर है, तो declare -p varएक declareकमांड को आउटपुट करता varहै जो चर को उसके वर्तमान प्रकार और मूल्य के लिए सेट करेगा , और स्थिति कोड 0(सफलता) देता है। यदि varअघोषित है, तो स्थिति कोड declare -p varको एक त्रुटि संदेश आउटपुट करता है । का उपयोग करते हुए , नियमित और आउटपुट दोनों को रीडायरेक्ट करता हैstderr1&>/dev/nullstdoutstderr/dev/null , कभी नहीं देखा जा सकता है, और स्थिति कोड को बदले बिना। इस प्रकार फ़ंक्शन केवल स्थिति कोड लौटाता है।

क्यों बाश में अन्य तरीके (कभी-कभी) विफल हो जाते हैं

  • [ -n "$var" ]: यह केवल जाँच करता है कि ${var[0]}क्या गैर-रिक्त है। (बैश में, $varजैसा है ${var[0]})
  • [ -n "${var+x}" ]: यह केवल जाँच करता है कि ${var[0]}क्या सेट है।
  • [ "${#var[@]}" != 0 ]: यह केवल जाँच करता है कि कम से कम एक इंडेक्स $varसेट है या नहीं।

जब यह विधि बैश में विफल हो जाती है

यह केवल नामित चरों (सहित के लिए काम करता है $_), नहीं कुछ विशेष चर ( $!, $@, $#, $$, $*, $?, $-, $0, $1, $2, ..., और किसी भी मैं भूल गए हैं सकता है)। चूँकि इनमें से कोई भी सारणी नहीं है, POSIX- शैली [ -n "${var+x}" ]इन सभी विशेष चरों के लिए काम करती है। लेकिन फ़ंक्शन में इसे लपेटने से सावधान रहें क्योंकि कई विशेष चर मूल्यों / अस्तित्व को बदलते हैं जब फ़ंक्शन कहलाते हैं।

शेल संगतता नोट

यदि आपकी स्क्रिप्ट में सरणियाँ हैं और आप इसे यथासंभव अधिक गोले के साथ संगत बनाने का प्रयास कर रहे हैं, तो typeset -pइसके बजाय का उपयोग करने पर विचार करें declare -p। मैंने पढ़ा है कि ksh केवल पूर्व का समर्थन करता है, लेकिन यह परीक्षण करने में सक्षम नहीं है। मुझे पता है कि बैश 3.0+ और Zsh 5.5.1 दोनों प्रत्येक समर्थन करते हैं typeset -pऔर declare -p, केवल अलग-अलग होते हैं जिसमें एक दूसरे के लिए एक विकल्प है। लेकिन मैंने उन दो खोजशब्दों के अंतरों का परीक्षण नहीं किया है, और मैंने अन्य गोले का परीक्षण नहीं किया है।

यदि आपको अपनी स्क्रिप्ट को POSIX sh संगत बनाने की आवश्यकता है, तो आप सरणियों का उपयोग नहीं कर सकते। बिना एरे के, [ -n "{$var+x}" ]काम करता है।

बैश में विभिन्न तरीकों के लिए तुलना कोड

यह फ़ंक्शन चर कोड को अनसेट करता है var, evalपास कोड को चलाता है, यह निर्धारित करने के लिए परीक्षण चलाता है कि क्या डी कोड varद्वारा निर्धारित किया गया है eval, और अंत में विभिन्न परीक्षणों के लिए परिणामी स्थिति कोड दिखाता है।

मैं लंघन कर रहा हूँ test -v var, [ -v var ]और [[ -v var ]]क्योंकि वे POSIX मानक के समान परिणाम[ -n "${var+x}" ] , बैश 4.2+ की आवश्यकता होती है, जबकि। मैं लंघन भी कर रहा हूँ typeset -pक्योंकि यह declare -pमेरे द्वारा परीक्षण किए गए गोले के रूप में ही है (बैश 3.0 के माध्यम से 5.0, और Zsh 5.5.1)।

is-var-set-after() {
    # Set var by passed expression.
    unset var
    eval "$1"

    # Run the tests, in increasing order of accuracy.
    [ -n "$var" ] # (index 0 of) var is nonempty
    nonempty=$?
    [ -n "${var+x}" ] # (index 0 of) var is set, maybe empty
    plus=$?
    [ "${#var[@]}" != 0 ] # var has at least one index set, maybe empty
    count=$?
    declare -p var &>/dev/null # var has been declared (any type)
    declared=$?

    # Show test results.
    printf '%30s: %2s %2s %2s %2s\n' "$1" $nonempty $plus $count $declared
}

टेस्ट केस कोड

ध्यान दें कि बैश नॉन-न्यूमेरिक ऐरे इंडिकेशंस को "0" मानने के कारण टेस्ट रिजल्ट अप्रत्याशित हो सकता है, अगर वेरिएबल को ऐररेटिव ऐरे के रूप में घोषित नहीं किया गया है। इसके अलावा, सहयोगी एरे केवल बश 4.0+ में मान्य हैं।

# Header.
printf '%30s: %2s %2s %2s %2s\n' "test" '-n' '+x' '#@' '-p'
# First 5 tests: Equivalent to setting 'var=foo' because index 0 of an
# indexed array is also the nonindexed value, and non-numerical
# indices in an array not declared as associative are the same as
# index 0.
is-var-set-after "var=foo"                        #  0  0  0  0
is-var-set-after "var=(foo)"                      #  0  0  0  0
is-var-set-after "var=([0]=foo)"                  #  0  0  0  0
is-var-set-after "var=([x]=foo)"                  #  0  0  0  0
is-var-set-after "var=([y]=bar [x]=foo)"          #  0  0  0  0
# '[ -n "$var" ]' fails when var is empty.
is-var-set-after "var=''"                         #  1  0  0  0
is-var-set-after "var=([0]='')"                   #  1  0  0  0
# Indices other than 0 are not detected by '[ -n "$var" ]' or by
# '[ -n "${var+x}" ]'.
is-var-set-after "var=([1]='')"                   #  1  1  0  0
is-var-set-after "var=([1]=foo)"                  #  1  1  0  0
is-var-set-after "declare -A var; var=([x]=foo)"  #  1  1  0  0
# Empty arrays are only detected by 'declare -p'.
is-var-set-after "var=()"                         #  1  1  1  0
is-var-set-after "declare -a var"                 #  1  1  1  0
is-var-set-after "declare -A var"                 #  1  1  1  0
# If 'var' is unset, then it even fails the 'declare -p var' test.
is-var-set-after "unset var"                      #  1  1  1  1

परीक्षण उत्पादन

शीर्ष लेख पंक्ति के अनुरूप में परीक्षण स्मृति सहायकों के लिए [ -n "$var" ], [ -n "${var+x}" ], [ "${#var[@]}" != 0 ], और declare -p var, क्रमशः।

                         test: -n +x #@ -p
                      var=foo:  0  0  0  0
                    var=(foo):  0  0  0  0
                var=([0]=foo):  0  0  0  0
                var=([x]=foo):  0  0  0  0
        var=([y]=bar [x]=foo):  0  0  0  0
                       var='':  1  0  0  0
                 var=([0]=''):  1  0  0  0
                 var=([1]=''):  1  1  0  0
                var=([1]=foo):  1  1  0  0
declare -A var; var=([x]=foo):  1  1  0  0
                       var=():  1  1  1  0
               declare -a var:  1  1  1  0
               declare -A var:  1  1  1  0
                    unset var:  1  1  1  1

सारांश

  • declare -p var &>/dev/null (100%?) कम से कम 3.0 के बाद से बैश में चर नाम के परीक्षण के लिए विश्वसनीय है।
  • [ -n "${var+x}" ] POSIX आज्ञाकारी स्थितियों में विश्वसनीय है, लेकिन सरणियों को संभाल नहीं सकता है।
  • अन्य परीक्षण यह जाँचने के लिए मौजूद हैं कि क्या कोई चर अ-रिक्त है, और अन्य गोले में घोषित चर के लिए जाँच के लिए। लेकिन ये परीक्षण न तो बैश और न ही पॉसिक्स स्क्रिप्ट के लिए अनुकूल हैं।

3
मैंने जिन उत्तरों की कोशिश की, उनमें से एक ( declare -p var &>/dev/nullकेवल) एक है जो काम करता है। धन्यवाद!
user1387866

2
@ mark-haferkamp मैंने आपके फ़ंक्शन कोड में महत्वपूर्ण पूर्ववर्ती "/" को जोड़ने के लिए आपके उत्तर को संपादित करने का प्रयास किया है, इसलिए यह पढ़ता है, ... &> /dev/nullलेकिन SO मुझे एक वर्ण संपादित नहीं करने देगा 🙄 (होना चाहिए> 6 वर्ण - यहां तक ​​कि श्वेत-स्थान जोड़ने की भी कोशिश की गई है लेकिन यह काम नहीं किया)। इसके अलावा, जब आप इंगित करते हैं कि $1वेरिएबल (जैसे OUTPUT_DIR) नामक एक नमूने के लिए स्विच करने के लिए फ़ंक्शन को बदलने के लायक हो सकता है , तो विशेष चर $1यहां काम नहीं करते हैं। वैसे भी, यह एक महत्वपूर्ण संपादन है अन्यथा कोड nullएक रिश्तेदार निर्देशिका नामक फ़ाइल बनाने के लिए देख रहा है dev। BTW - महान जवाब!
जोहाना

इसके अलावा, $ उपसर्ग के बिना चर के नाम का उपयोग करना भी काम करता है: declare -p PATH &> /dev/nullरिटर्न 0 के रूप में जहां declare -p ASDFASDGFASKDF &> /dev/nullरिटर्न 1. (बैश 5.0.11 पर (1)
-release

1
अच्छा कार्य! सावधानी के 1 शब्द: declare varvar को एक वेरिएबल घोषित करता है, लेकिन इसे इसके संदर्भ में सेट नहीं करता है set -o nounset: Test withdeclare foo bar=; set -o nounset; echo $bar; echo $foo
xebeche

@joehanna उस लापता को पकड़ने के लिए धन्यवाद /! मैंने यह तय किया, लेकिन मुझे लगता है कि तर्क एक फ़ंक्शन को वारंट करने के लिए पर्याप्त भ्रमित कर रहा है, विशेष रूप से @ xebeche की टिप्पणी के प्रकाश में। @xebeche यह मेरे उत्तर के लिए असुविधाजनक है। ... ऐसा लगता है कि मुझे कुछ ऐसा करने की कोशिश करनी होगी declare -p "$1" | grep =या test -v "$1"
मार्क हैफरकैम्प

19

उन लोगों के लिए जो किसी स्क्रिप्ट में अनसेट या खाली होने की जाँच कर रहे हैं set -u:

if [ -z "${var-}" ]; then
   echo "Must provide var environment variable. Exiting...."
   exit 1
fi

नियमित रूप से [ -z "$var" ]चेक के साथ असफल हो जायेगी var; unbound variableअगर set -uलेकिन [ -z "${var-}" ] फैलता स्ट्रिंग खाली करने के लिए करता है, तो varनाकाम रहने के बिना सेट नहीं की जाती।


आपको एक बृहदान्त्र याद आ रहा है। यह होना चाहिए ${var:-}, नहीं ${var-}। लेकिन बैश में, मैं यह पुष्टि कर सकता हूं कि यह बृहदान्त्र के बिना भी काम करता है।
पालेक

3
${var:-}और ${var-}विभिन्न चीजों का मतलब है। ${var:-}यदि स्ट्रिंग खाली करने के लिए विस्तार होगा varसेट किए बिना या नल और ${var-}केवल तभी सेट किए बिना रिक्त स्ट्रिंग पर विस्तार होगा।
RubenLaguna

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

17

यदि आप परेशान हैं तो आप बाहर निकलना चाहते हैं

इसने मेरे लिए काम किया। मैं चाहता था कि मेरी स्क्रिप्ट एक त्रुटि संदेश के साथ बाहर निकले अगर कोई पैरामीटर सेट नहीं था।

#!/usr/bin/env bash

set -o errexit

# Get the value and empty validation check all in one
VER="${1:?You must pass a version of the format 0.0.0 as the only argument}"

जब यह चलाया जाता है तो यह एक त्रुटि के साथ लौटता है

peek@peek:~$ ./setver.sh
./setver.sh: line 13: 1: You must pass a version of the format 0.0.0 as the only argument

केवल जाँच करें, कोई निकास नहीं - खाली और परेशान INVALID हैं

इस विकल्प को आज़माएं यदि आप यह जांचना चाहते हैं कि मान सेट किया गया है / वैध या परेशान / खाली = INVALID।

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
if [ "${TUNSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

या, यहां तक ​​कि छोटे परीक्षण ;-)

[ "${TSET:-}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY:-}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET:-}" ] && echo "VALID" || echo "INVALID"

केवल चेक करें, कोई निकास नहीं - केवल खाली है INVALID

और यह सवाल का जवाब है। यदि आप केवल यह जानना चाहते हैं कि मान सेट / खाली = VALID या परेशान = INVALID है या नहीं।

ध्यान दें, "1" में "..- 1}" महत्वहीन है, यह कुछ भी हो सकता है (जैसे x)

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TUNSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

लघु परीक्षण

[ "${TSET+1}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY+1}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET+1}" ] && echo "VALID" || echo "INVALID"

मैं इस उत्तर को @ mklement0 (टिप्पणियों) को समर्पित करता हूं जिन्होंने मुझे इस सवाल का सही उत्तर देने के लिए चुनौती दी।

संदर्भ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02


15

यह जांचने के लिए कि क्या कोई चर नॉन-खाली मान के साथ सेट किया गया है, उपयोग करें [ -n "$x" ], जैसा कि दूसरों ने पहले ही संकेत दिया है।

अधिकांश समय, एक चर के इलाज के लिए एक अच्छा विचार है जो एक चर के समान खाली मूल्य है जो कि परेशान है। लेकिन आप दोनों को अलग कर सकते हैं यदि आपको जरूरत है: [ -n "${x+set}" ]( "${x+set}"विस्तार करने के लिए setअगर xसेट है और खाली स्ट्रिंग में अगर xपरेशान है)।

यह जांचने के लिए कि क्या कोई पैरामीटर पारित किया गया है, परीक्षण करें $#, जो फ़ंक्शन (या स्क्रिप्ट में, जब एक फ़ंक्शन में नहीं है) को दिए गए मापदंडों की संख्या है (देखें पॉल का जवाब )।


14

के "पैरामीटर विस्तार" अनुभाग पढ़ें bashमैन पेज । पैरामीटर विस्तार सेट किए जा रहे चर के लिए एक सामान्य परीक्षण प्रदान नहीं करता है, लेकिन कई चीजें हैं जो आप एक पैरामीटर के लिए कर सकते हैं यदि यह सेट नहीं है।

उदाहरण के लिए:

function a {
    first_arg=${1-foo}
    # rest of the function
}

असाइन किए first_argजाने पर बराबर सेट होगा $1, अन्यथा यह "फू" मान का उपयोग करता है। अगरa बिल्कुल एकल पैरामीटर लेना चाहिए, और कोई अच्छा डिफ़ॉल्ट मौजूद नहीं है, तो जब कोई पैरामीटर नहीं दिया जाता है, तो आप एक त्रुटि संदेश के साथ बाहर निकल सकते हैं:

function a {
    : ${1?a must take a single argument}
    # rest of the function
}

(नोट के :रूप में एक अशक्त कमांड के उपयोग पर ध्यान दें , जो सिर्फ इसके तर्कों के मूल्यों का विस्तार करता है। हम $1इस उदाहरण के साथ कुछ भी नहीं करना चाहते हैं , बस बाहर निकलें अगर यह सेट नहीं है)


1
मैं चकित हूं कि अन्य उत्तरों में से कोई भी सरल और सुरुचिपूर्ण उल्लेख नहीं करता है : ${var?message}
ट्रिपल

आप इसे कहाँ से ले गए थे? आश्चर्यजनक! यह काम करता है! और यह छोटा और सुरुचिपूर्ण है! धन्यवाद!
रोजर

13

बाश में आप बिलिन के -vअंदर उपयोग कर सकते हैं [[ ]]:

#! /bin/bash -u

if [[ ! -v SOMEVAR ]]; then
    SOMEVAR='hello'
fi

echo $SOMEVAR

8

उपयोग करना [[ -z "$var" ]]यह जानने का सबसे आसान तरीका है कि एक चर सेट किया गया था या नहीं, लेकिन यह विकल्प -zएक अस्थिर चर और एक खाली स्ट्रिंग के लिए चर के बीच अंतर नहीं करता है:

$ set=''
$ [[ -z "$set" ]] && echo "Set" || echo "Unset" 
Unset
$ [[ -z "$unset" ]] && echo "Set" || echo "Unset"
Unset

चर के प्रकार के अनुसार इसे जांचना सबसे अच्छा है: env चर, पैरामीटर या नियमित चर।

एक एनवी चर के लिए:

[[ $(env | grep "varname=" | wc -l) -eq 1 ]] && echo "Set" || echo "Unset"

एक पैरामीटर के लिए (उदाहरण के लिए, पैरामीटर के अस्तित्व की जांच करने के लिए $5):

[[ $# -ge 5 ]] && echo "Set" || echo "Unset"

एक नियमित चर (सहायक फ़ंक्शन का उपयोग करके, इसे सुरुचिपूर्ण तरीके से करने के लिए):

function declare_var {
   declare -p "$1" &> /dev/null
}
declare_var "var_name" && echo "Set" || echo "Unset"

टिप्पणियाँ:

  • $#: आपको स्थितिगत मापदंडों की संख्या देता है।
  • declare -p: आपको एक पैरामीटर के रूप में पारित चर की परिभाषा देता है। यदि यह मौजूद है, तो 0 लौटाता है, यदि नहीं, तो 1 लौटाता है और एक त्रुटि संदेश प्रिंट करता है।
  • &> /dev/null:declare -p इसके रिटर्न कोड को प्रभावित किए बिना आउटपुट को दबा देता है ।

5

बैश विकल्प set -uसक्षम होने पर ऊपर दिए गए उत्तर काम नहीं करते हैं । इसके अलावा, वे गतिशील नहीं हैं, उदाहरण के लिए, "डमी" नाम के साथ परीक्षण कैसे किया जाता है? इसे इस्तेमाल करे:

is_var_defined()
{
    if [ $# -ne 1 ]
    then
        echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
        exit 1
    fi
    # Tricky.  Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
    # is defined with this construct: [ ! -z "$var" ].  Instead, we must use default value
    # substitution with this construct: [ ! -z "${var:-}" ].  Normally, a default value follows the
    # operator ':-', but here we leave it blank for empty (null) string.  Finally, we need to
    # substitute the text from $1 as 'var'.  This is not allowed directly in Bash with this
    # construct: [ ! -z "${$1:-}" ].  We need to use indirection with eval operator.
    # Example: $1="var"
    # Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
    # Code  execute: [ ! -z ${var:-} ]
    eval "[ ! -z \${$1:-} ]"
    return $?  # Pedantic.
}

संबंधित: बैश में, मैं कैसे परीक्षण करूं कि कोई चर "-यू" मोड में परिभाषित किया गया है


1
मैं इतना जानना चाहूंगा कि यह उत्तर क्यों अस्वीकृत किया गया ... मेरे लिए बहुत अच्छा काम करता है।
लावास्कॉक्डऑवन

बाश में, आप एक ही के बिना कर सकते हैं: eval "[ ! -z \${$1:-} ]"अप्रत्यक्ष मूल्यांकन में परिवर्तन [ ! -z ${!1:-} ];:।

@BinaryZebra: दिलचस्प विचार। मेरा सुझाव है कि आप एक अलग उत्तर के रूप में पोस्ट करें।
केविनरपे

"Eval" का उपयोग इस समाधान को कोड इंजेक्शन के लिए असुरक्षित बनाता है: $ is_var_defined 'x}]; इको "गोच"> & 2; # #
गोत्र

4

तुम कर सकते हो:

function a {
        if [ ! -z "$1" ]; then
                echo '$1 is set'
        fi
}

9
या आप कर सकते हैं -nऔर नकारात्मक नहीं -z
अगली सूचना तक रोक दिया गया।

1
आप के आसपास उद्धरण की आवश्यकता है $1, यानी [ ! -z "$1" ]। या आप [[ ! -z $1 ]]bash / ksh / zsh में लिख सकते हैं ।
गिल्स एसओ- बुराई को रोकना '

5
यह $1रिक्त स्ट्रिंग पर सेट होने पर विफल हो जाएगा ।
हैलोगूडीबाई

4

मेरा पसंदीदा तरीका यह है:

$ var=10
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
is set
$ unset -v var
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
NOT set

तो मूल रूप से, यदि एक चर सेट किया जाता है, तो यह "परिणाम की एक नकारात्मकता" बन जाता है false(क्या होगा true= "सेट किया गया है")।

और, अगर यह परेशान है, तो यह true"परिणाम का एक निषेध" बन जाएगा (जैसा कि खाली परिणाम का मूल्यांकन करता है true) (इसलिए समाप्त होने के रूप में false= "सेट नहीं")।



1

एक शेल में आप -zऑपरेटर का उपयोग कर सकते हैं जो सही है यदि स्ट्रिंग की लंबाई शून्य है।

डिफ़ॉल्ट सेट करने के लिए एक सरल-लाइनर MY_VARयदि यह सेट नहीं है, तो वैकल्पिक रूप से आप संदेश प्रदर्शित कर सकते हैं:

[[ -z "$MY_VAR" ]] && MY_VAR="default"
[[ -z "$MY_VAR" ]] && MY_VAR="default" || echo "Variable already set."

0
if [[ ${1:+isset} ]]
then echo "It was set and not null." >&2
else echo "It was not set or it was null." >&2
fi

if [[ ${1+isset} ]]
then echo "It was set but might be null." >&2
else echo "It was was not set." >&2
fi

$1, $2और अप करने के लिए $Nहमेशा के लिए निर्धारित है। क्षमा करें, यह विफल है।

मैंने इसकी कोशिश की, और यह काम नहीं किया, हो सकता है कि मेरे बैश संस्करण में उसके लिए समर्थन का अभाव हो। अगर मैं गलत हूं तो क्षमा करें। :)

0

मुझे ऐसा करने के लिए एक (बहुत) बेहतर कोड मिला यदि आप किसी भी चीज़ की जांच करना चाहते हैं $@

अगर [[$ 1 = ""]]
फिर
  गूंज '$ 1 खाली है'
अन्य
  गूंज '$ 1 भरा है'
फाई

यह सब क्यों? में सब कुछ $@बैश में मौजूद है, लेकिन डिफ़ॉल्ट रूप से यह खाली है, तो test -zऔर test -nतुम्हारी मदद नहीं कर सका।

अद्यतन: आप एक पैरामीटर में वर्णों की संख्या भी गिन सकते हैं।

अगर [$ {# 1} = 0]
फिर
  गूंज '$ 1 खाली है'
अन्य
  गूंज '$ 1 भरा है'
फाई

मुझे पता है, लेकिन यह बात है। अगर कुछ खाली है तो आपको एक त्रुटि मिलेगी! माफ़ करना। : पी

0
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi

11
StackOverflow में आपका स्वागत है। जबकि आपके उत्तर की सराहना की जाती है, यह सिर्फ कोड से अधिक देने के लिए सबसे अच्छा है। क्या आप अपने उत्तर या छोटे स्पष्टीकरण के लिए तर्क जोड़ सकते हैं? अपने उत्तर के विस्तार के लिए अन्य विचारों के लिए इस पृष्ठ को देखें ।
सेलेओ

0

यह वही है जो मैं हर दिन उपयोग करता हूं:

#
# Check if a variable is set
#   param1  name of the variable
#
function is_set()
{
    [[ -n "${1}" ]] && test -n "$(eval "echo "\${${1}+x}"")"
}

यह लिनक्स और सोलारिस के नीचे 3.0 को कोसने के लिए अच्छी तरह से काम करता है।

bash-3.00$ myvar="TEST"
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ mavar=""
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ unset myvar
bash-3.00$ is_set myvar ; echo $?
1

1
चूंकि बाश 2.0+ अप्रत्यक्ष विस्तार उपलब्ध है। आप test -n "$(eval "echo "\${${1}+x}"")"समतुल्य के लिए लंबे और जटिल (एक eval के साथ भी) को प्रतिस्थापित कर सकते हैं :[[ ${!1+x} ]]

0

मुझे बैश के कच्चे विवरण को छिपाने के लिए सहायक कार्य पसंद हैं। इस मामले में, ऐसा करना और भी अधिक (छिपा हुआ) असमानता जोड़ता है:

# The first ! negates the result (can't use -n to achieve this)
# the second ! expands the content of varname (can't do ${$varname})
function IsDeclared_Tricky
{
  local varname="$1"
  ! [ -z ${!varname+x} ]
}

क्योंकि मेरे पास पहले इस कार्यान्वयन में कीड़े थे (जेन्स और लियोनेल के उत्तर से प्रेरित), मैं एक अलग समाधान के साथ आया था:

# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
  declare -p $1 &>/dev/null
}

मुझे यह अधिक सीधा-साधा, अधिक उबाऊ और समझने / याद रखने में आसान लगता है। टेस्ट केस दिखाता है कि यह समकक्ष है:

function main()
{
  declare -i xyz
  local foo
  local bar=
  local baz=''

  IsDeclared_Tricky xyz; echo "IsDeclared_Tricky xyz: $?"
  IsDeclared_Tricky foo; echo "IsDeclared_Tricky foo: $?"
  IsDeclared_Tricky bar; echo "IsDeclared_Tricky bar: $?"
  IsDeclared_Tricky baz; echo "IsDeclared_Tricky baz: $?"

  IsDeclared xyz; echo "IsDeclared xyz: $?"
  IsDeclared foo; echo "IsDeclared foo: $?"
  IsDeclared bar; echo "IsDeclared bar: $?"
  IsDeclared baz; echo "IsDeclared baz: $?"
}

main

परीक्षण का मामला यह भी दिखाता है कि जब तक (= '' के बाद) var घोषित नहींlocal var होता है । काफी समय से मुझे लगा कि मैंने इस तरह से चर घोषित कर दिए हैं, बस अब यह पता लगाने के लिए कि मैंने केवल अपना इरादा व्यक्त किया है ... यह एक नो-ऑप है, मुझे लगता है।

IsDeclared_Tricky xyz: 1
IsDeclared_Tricky फू: 1
IsDeclared_Tricky बार: 0
IsDeclared_Tricky baz: 0
IsDeclared xyz: 1
IsDeclared foo: 1
IsDeclared bar: 0
IsDeclared baz: 0

बोनस: usecase

मैं इस परीक्षण का उपयोग कुछ हद तक "सुरुचिपूर्ण" और सुरक्षित तरीके से कार्य करने के लिए (और वापसी) मापदंडों का उपयोग करता हूं (लगभग एक इंटरफ़ेस जैसा ...::

#auxiliary functions
function die()
{
  echo "Error: $1"; exit 1
}

function assertVariableDeclared()
{
  IsDeclared "$1" || die "variable not declared: $1"
}

function expectVariables()
{
  while (( $# > 0 )); do
    assertVariableDeclared $1; shift
  done
}

# actual example
function exampleFunction()
{
  expectVariables inputStr outputStr
  outputStr="$inputStr world!"
}

function bonus()
{
  local inputStr='Hello'
  local outputStr= # remove this to trigger error
  exampleFunction
  echo $outputStr
}

bonus

अगर सभी को घोषित चर की आवश्यकता होती है:

नमस्ते दुनिया!

अन्य:

त्रुटि: चर घोषित नहीं: outputStr


0

सभी उत्तरों को संक्षिप्त करने के बाद, यह भी काम करता है:

if [[ -z $SOME_VAR ]]; then read -p "Enter a value for SOME_VAR: " SOME_VAR; fi
echo "SOME_VAR=$SOME_VAR"

यदि आपके पास SOME_VARमेरे स्थान पर नहीं है $SOME_VAR, तो यह इसे एक खाली मूल्य पर सेट करेगा; $इसके लिए काम करना आवश्यक है।


जब आप set -uप्रभाव में होंगे तो वह काम नहीं करेगा जो unboud variableत्रुटि को प्रिंट करेगा
माइकल ह्युबर्गर

-1

यह जाँचने के लिए कि कोई var सेट है या नहीं

var=""; [[ $var ]] && echo "set" || echo "not set"

3
यह $varरिक्त स्ट्रिंग पर सेट होने पर विफल हो जाएगा ।
हैलोगूडीबाई

-1

यदि आप परीक्षण करना चाहते हैं कि एक चर बाउंड या अनबाउंड है, तो यह अच्छी तरह से काम करता है, भले ही आप संज्ञा विकल्प पर मुड़ गए हों:

set -o noun set

if printenv variableName >/dev/null; then
    # variable is bound to a value
else
    # variable is unbound
fi

मुझे लगता है कि आपका मतलब है set -o nounset, नहीं set -o noun set। यह केवल उन चरों के लिए काम करता है जो exportएड किए गए हैं। यह आपकी सेटिंग्स को एक तरह से बदल देता है जो पूर्ववत करना अजीब है।
कीथ थॉम्पसन

-1

मैं हमेशा इस का उपयोग करता हूं, इस तथ्य के आधार पर कि किसी को भी समझना आसान लगता है जो पहली बार कोड देखता है:

if [ "$variable" = "" ]
    then
    echo "Variable X is empty"
fi

और, अगर खाली नहीं है तो जांचना चाहते हैं;

if [ ! "$variable" = "" ]
    then
    echo "Variable X is not empty"
fi

बस।


4
प्रश्न पूछता है कि कैसे जांचा जाए कि कोई चर निर्धारित किया गया है, न कि यदि कोई चर खाली है।
हैलोगूडीबाई

आपको शायद [[ ... ]]इसके बजाय उपयोग करने की आवश्यकता है [ ... ]। उत्तरार्द्ध वास्तव में एक बाहरी कमांड है और इसमें कोई दृश्यता नहीं होगी कि एक चर सेट किया गया है या नहीं।
ठोस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.