[-N] [-n ""] की तरह झूठ क्यों नहीं है?


20

मेरा प्रश्न इस कोड द्वारा निर्मित रिटर्न वैल्यू पर है:

if [ -n ]; then echo "true"; else echo "false"; fi

यह प्रिंट करता है true

इसके पूरक परीक्षण [ -z ]भी प्रिंट का उपयोग कर true:

if [ -z ]; then echo "true"; else  echo "false"; fi

उपरोक्त कोड में, [ -n ]परीक्षण स्ट्रिंग मान को क्यों नहीं मान लेता है जो बिल्कुल भी पास नहीं है, क्योंकि शून्य नहीं है?

प्रिंट के नीचे का कोड false। पारित स्ट्रिंग मान शून्य और शून्य लंबाई के बाद से यह अपेक्षित है।

if [ -n "" ]; then echo "true"; else  echo "false"; fi

जवाबों:


14

[एक्स] के बराबर है [ -nएक्स] भले ही एक्स के साथ शुरू होता है -बशर्ते कोई संकार्य है।

$ [ -o ] ; echo $?
0
$ [ -eq ] ; echo $?
0
$ [ -n -o ] ; echo $?
0
$ [ -n -eq ] ; echo $?
0

4
ध्यान दें कि ऐतिहासिक रूप से, [ -t ]परीक्षण कर रहा था कि क्या stdout एक टर्मिनल था (छोटा है [ -t 1 ]) और कुछ गोले अभी भी कर रहे हैं ( ksh93केवल मामले में जब वह -tशाब्दिक है), इसलिए इसका उपयोग करना बेहतर [ -n "$var" ]है [ "$var" ]। हालांकि है कि अभी भी कुछ पुराने में विफल हो जाएगा testके मूल्यों के लिए कार्यान्वयन $varकी तरह =, जिस स्थिति में [ "" != "$var" ]या [ "x$var" != x ]या case $x in "")...बेहतर हो सकता है।
स्टीफन चेज़लस

3
दिलचस्प है -oयहाँ का चुनाव । जैसे कुछ गोले में bash, -oदोनों एक एकरी (परीक्षण यदि कोई विकल्प सेट है) और बाइनरी (या) ऑपरेटर है, तो ऐसी चीजें [ ! -o monitor ]अस्पष्ट हैं। यह परीक्षण कर रहा है कि monitorविकल्प सेट नहीं है, या कि या तो !या monitorगैर खाली तार कर रहे हैं? POSIX नियम तय करते हैं: बाद वाला (जो अलग है [[ ! -o monitor ]])।
स्टीफन चेज़लस

30

[ -n ]-nपरीक्षण का उपयोग नहीं करता है ।

-nमें [ -n ]सभी में एक परीक्षण नहीं है। जब वहाँ के बीच केवल एक ही तर्क है [और ], उस कथन की एक स्ट्रिंग है कि यदि यह रिक्त है देखने के लिए परीक्षण किया जाता है है। यहां तक ​​कि जब उस स्ट्रिंग में एक अग्रणी होता है -, तब भी इसे एक ऑपरेंड के रूप में व्याख्या किया जाता है, एक परीक्षण नहीं। चूंकि स्ट्रिंग -nखाली नहीं है - इसमें दो वर्ण हैं, -और n, शून्य वर्ण नहीं हैं -[ -n ] सत्य का मूल्यांकन करता है।

जैसा कि इग्नासियो वाज़केज़-अब्राम्स कहते हैं , जहां stringएक ही तर्क है, जिस पर परीक्षण किया गया stringहै , वह उसी तरह है जिस पर परीक्षण किया गया था । कब क्या हो जाए , कुछ खास नहीं होता। में और दूसरे में बस तार कर रहे हैं खालीपन के लिए परीक्षण किया जा रहा।[ string ][ -n string ]string-n-n[ -n ]-n[ -n -n ]

जब आपस में केवल एक ही तर्क होता है , [और ]उस तर्क को हमेशा गैर-बराबरी के लिए जांचा जाने वाला एक स्ट्रिंग है, भले ही ऐसा हो कि इसे एक परीक्षण के रूप में नाम दिया जाए। इसी तरह, जब दोनों के बीच दो तर्क होते हैं [और ]उनमें से पहला होता है -n, दूसरा हमेशा अनिद्रा के लिए परीक्षण किया जाने वाला एक स्ट्रिंग है, भले ही ऐसा हो कि इसे परीक्षण के रूप में नाम दिया जाए। यह केवल इसलिए है क्योंकि वाक्यविन्यास [जोर देता है कि एक स्ट्रिंग ऑपरेटर के बीच [और ]बाद -nमें एक एकल तर्क है।

एक ही कारण है कि के लिए [ -n ]उपयोग नहीं करता है -nपरीक्षण, [ -z ]का उपयोग नहीं करता -zपरीक्षण।


आप इसके लिए मदद की जांच करके इसके बारे [में अधिक जान सकते हैं bash। सूचना है कि एक शेल बनाया गया है :

$ type [
[ is a shell builtin

इस प्रकार आप इस help [पर सहायता प्राप्त करने के लिए दौड़ सकते हैं :

$ help [
[: [ arg... ]
    Evaluate conditional expression.

    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.

अधिक जानकारी के लिए, क्या परीक्षण समर्थित हैं और वे कैसे काम करते हैं, सहित, आपको मदद को देखना होगा test। जब आप कमांड चलाते हैं help test, तो आपको एक विस्तृत सूची मिलेगी। यह सब पुन: पेश करने के बजाय, यहाँ स्ट्रिंग ऑपरेटरों के बारे में हिस्सा है:

      -z STRING      True if string is empty.

      -n STRING
         STRING      True if string is not empty.

      STRING1 = STRING2
                     True if the strings are equal.
      STRING1 != STRING2
                     True if the strings are not equal.
      STRING1 < STRING2
                     True if STRING1 sorts before STRING2 lexicographically.
      STRING1 > STRING2
                     True if STRING1 sorts after STRING2 lexicographically.

ध्यान दें कि -n STRINGऔर बस STRINGएक ही काम करें: वे परीक्षण करते हैं कि क्या स्ट्रिंग STRINGखाली नहीं है।


2
अच्छी व्याख्या
सेर्गेई कोलोडियाज़नी

1
: शायद यह भी है कि इस गैर उद्धृत चर सेट नहीं कर रहे हैं, इस तरह के लिए निहितार्थ है उल्लेख paste.ubuntu.com/25831047
सर्गी Kolodyazhnyy

1
@SergiyKolodyazhnyy मुझे लगता है कि यह एक अलग जवाब में बेहतर हो सकता है। वेरीएबल्स जो IFSपरेशान हैं, या सेट किए गए हैं, लेकिन खाली हैं, या केवल व्हाट्सएप हैं, वे ऐसा करेंगे; चर जिसमें शून्य के बजाय कई शब्द होते हैं, एक और प्रभाव पैदा करते हैं और एक पूरी तरह से अलग परीक्षण चलाने का कारण बन सकते हैं। ऑपरेंड होने के इरादे से प्रतीत होने वाले स्ट्रिंग्स केवल तभी ठीक से काम करेंगे जब उनके पास कोई स्थान या टैब न हो या यदि वे उद्धृत किए गए हों। यदि मैं इस विषय को सुलभ तरीके से कवर करता तो उत्तर बहुत लंबा और अधिक जटिल हो जाता। यदि आप उत्तर पोस्ट करने का निर्णय लेते हैं, तो इसके बारे में मुझे यहाँ पर नि: संकोच महसूस करें!
एलियाह कगन

@ अली कगन, आपका उत्तर अधिक पूर्ण और विस्तृत है, हालांकि इग्नासियो वाज़क्वेज़-अब्राम्स की प्रतिक्रिया ने मेरे प्रश्न का उत्तर दिया।
रवि कुमार

1
मुझे लगता है कि आप इसका कारण याद कर रहे हैं और इस तरह से है: यदि नहीं, [ "$var" ]तो परीक्षण के रूप में उपयोग करने योग्य नहीं होगा क्योंकि इसका $varविस्तार हो सकता है -n
आर ..

12

[ -n ]यह सत्य है क्योंकि [कमांड (उर्फ testकमांड) उसके दिए गए तर्कों की संख्या पर कार्य करता है । यदि इसे केवल एक तर्क दिया जाता है, तो परिणाम "सत्य" है यदि तर्क एक गैर-रिक्त स्ट्रिंग है। "-n" 2 अक्षरों वाला एक स्ट्रिंग है, खाली नहीं है, इसलिए "सच" है।

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