सवाल बैश में डबल और सिंगल स्क्वायर ब्रैकेट के बीच क्या अंतर है?


मैंने बस सोचा कि वास्तव में क्या अंतर है

[[ $STRING != foo ]]

तथा

[ $STRING != foo ]

है, इसके अलावा उत्तरार्द्ध posix-compliant है, sh में पाया गया है और पूर्व बैश में पाया गया एक विस्तार है।


344
2017-08-09 21:11


मूल


stackoverflow.com/questions/13542832 - Ciro Santilli 新疆改造中心 六四事件 法轮功
यदि आप किसी भी ब्रैकेट का उपयोग करने के बारे में भी सोच रहे थे, उदाहरण के लिए एक के संदर्भ में if बयान, देखें mywiki.wooledge.org/BashPitfalls#if_.5Bgrep_foo_myfile.5D - Kev
उबंटू के दस्तावेज़ों से भी: wiki.ubuntu.com/... - radistao


जवाब:


कई मतभेद हैं। मेरी राय में, कुछ सबसे महत्वपूर्ण हैं:

  1. [ बैश और कई अन्य आधुनिक गोले में एक बिल्टिन है। बिल्टिन [ के समान है test बंद होने की अतिरिक्त आवश्यकता के साथ ]। बिल्टिन [ तथा test कार्यक्षमता की नकल करें /bin/[ तथा /bin/test उनकी सीमाओं के साथ ताकि स्क्रिप्ट पीछे संगत हों। मूल निष्पादन योग्य अभी भी POSIX अनुपालन और पिछड़ा संगतता के लिए मौजूद हैं। आदेश चल रहा है type [ बैश में इंगित करता है कि [ डिफ़ॉल्ट रूप से एक अंतर्निहित के रूप में व्याख्या किया जाता है। (ध्यान दें: which [ केवल निष्पादन योग्य के लिए देखता है पथ और बराबर है type -p [)
  2. [[ संगत नहीं है, यह जरूरी नहीं है कि जो भी हो /bin/sh इशारा करना। इसलिए [[ अधिक आधुनिक बैश / जेएसएच / क्ष विकल्प है।
  3. इसलिये [[ खोल में बनाया गया है और विरासत की आवश्यकता नहीं है, आपको शब्द विभाजन के बारे में चिंता करने की आवश्यकता नहीं है भारतीय विदेश सेवा वैरिएबल पर गड़बड़ करने के लिए चर जो रिक्त स्थान के साथ एक स्ट्रिंग का मूल्यांकन करते हैं। इसलिए, आपको वास्तव में चर को डबल कोट्स में रखने की आवश्यकता नहीं है।

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

  1. आपको परीक्षण के बाईं ओर उद्धृत करने की चिंता करने की आवश्यकता नहीं है ताकि इसे वास्तव में एक चर के रूप में पढ़ा जा सके।
  2. आपको उससे कम से कम बचने की ज़रूरत नहीं है < > उनके लिए बैकस्लाश के साथ इनपुट रीडायरेक्शन के रूप में मूल्यांकन नहीं किया जा सकता है, जो वास्तव में फाइलों को ओवरराइट करके कुछ चीजें गड़बड़ कर सकता है। यह फिर से वापस चला जाता है [[ एक बिल्टिन होने के नाते। यदि [(टेस्ट) एक बाहरी कार्यक्रम है तो शैल को मूल्यांकन के तरीके में अपवाद करना होगा < तथा > केवल /bin/test कहा जा रहा है, जो वास्तव में समझ में नहीं आता है।

261
2017-08-09 21:56



धन्यवाद, बैश FAQ का लिंक वह था जिसे मैं ढूंढ रहा था (उस पृष्ठ के बारे में नहीं पता था, धन्यवाद)। - 0x89
मैंने आपकी पोस्ट को इस जानकारी के साथ संपादित किया है, लेकिन [और परीक्षण को बिल्टिन के रूप में निष्पादित किया जाता है। बिल्टिन को / bin / [और / bin / test को प्रतिस्थापित करने के लिए डिज़ाइन किया गया था, लेकिन बाइनरी की सीमाओं को पुन: उत्पन्न करने के लिए भी आवश्यक था। आदेश 'प्रकार [' सत्यापित करता है कि बिल्टिन का उपयोग किया जाता है। 'जो [' केवल पैथ पर निष्पादन योग्य खोज करता है और 'टाइप-पी [' के बराबर है - klynch


संक्षेप में:

[एक बाश है अंतर्निहित

[[]] बाश हैं कीवर्ड

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

  $ [ a < b ]
 -bash: b: No such file or directory
  $ [[ a < b ]]

पहला उदाहरण एक त्रुटि देता है क्योंकि बैश फ़ाइल बी को कमांड [a] पर रीडायरेक्ट करने का प्रयास करता है। दूसरा उदाहरण वास्तव में वह करता है जो आप इसकी अपेक्षा करते हैं। चरित्र <अब फ़ाइल रीडायरेक्शन ऑपरेटर का विशेष अर्थ नहीं है।

स्रोत: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments


108
2017-12-29 19:42



[ एक पॉज़िक्स खोल कमांड है; इसे बनाने की जरूरत नहीं है। ] सिर्फ एक तर्क है कि वह आदेश दिखता है, ताकि वाक्यविन्यास संतुलित हो। आदेश के लिए समानार्थी है test सिवाय इसके कि test बंद करने की तलाश नहीं है ]। - Kaz
यहाँ देखें: pubs.opengroup.org/onlinepubs/009695399/utilities/test.html - Kaz


व्यवहार मतभेद

बैश 4.3.11 में परीक्षण किया गया:

  • पॉसिक्स बनाम बैश एक्सटेंशन:

  • नियमित कमांड बनाम जादू

    • [ एक अजीब नाम के साथ सिर्फ एक नियमित आदेश है।

      ] सिर्फ एक तर्क है [ जो इस्तेमाल होने से आगे के तर्कों को रोकता है।

      उबंटू 16.04 वास्तव में इसके लिए एक निष्पादन योग्य है /usr/bin/[ कोर्यूटिल्स द्वारा प्रदान किया गया है, लेकिन बैश निर्मित संस्करण को प्राथमिकता दी जाती है।

      बैश ने आदेश को पार करने के तरीके में कुछ भी नहीं बदला है।

      विशेष रूप से, < पुनर्निर्देशन है, && तथा || एकाधिक आदेशों को संयोजित करें, ( ) बचने तक उपशीर्षक उत्पन्न करता है \, और शब्द विस्तार सामान्य के रूप में होता है।

    • [[ X ]] एक एकल निर्माण है जो बनाता है X जादुई रूप से पार्स किया जाना चाहिए। <, &&, || तथा () विशेष रूप से इलाज किया जाता है, और शब्द विभाजन नियम अलग हैं।

      जैसे आगे मतभेद भी हैं = तथा =~

    Bashese में: [ एक अंतर्निहित कमांड है, और [[ एक कीवर्ड है: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword

  • <

    • [[ a < b ]]: शब्दावली तुलना
    • [ a \< b ]: ऊपर की तरह। \ आवश्यक है या फिर किसी अन्य आदेश के लिए पुनर्निर्देशन करता है। बैश विस्तार।
    • मुझे इसके लिए एक पॉज़िक्स विकल्प नहीं मिला, देखें: https://stackoverflow.com/questions/21294867/how-to-test-strings-for-less-than-or-equal
  • && तथा ||

    • [[ a = a && b = b ]]: सच, तार्किक और
    • [ a = a && b = b ]: वक्य रचना त्रुटि, && एक और कमांड विभाजक के रूप में पार्स किया गया cmd1 && cmd2 
    • [ a = a -a b = b ]: समकक्ष, लेकिन POSIX द्वारा बहिष्कृत
    • [ a = a ] && [ b = b ]: POSIX सिफारिश
  • (

    • [[ (a = a || a = b) && a = b ]]: असत्य
    • [ ( a = a ) ]: वक्य रचना त्रुटि, () एक सबहेल के रूप में व्याख्या किया जाता है
    • [ \( a = a -o a = b \) -a a = b ]समकक्ष, लेकिन () POSIX द्वारा बहिष्कृत किया गया है
    • ([ a = a ] || [ a = b ]) && [ a = b ] POSIX सिफारिश
  • शब्द विभाजन

    • x='a b'; [[ $x = 'a b' ]]: सच, उद्धरण की आवश्यकता नहीं है
    • x='a b'; [ $x = 'a b' ]: वाक्यविन्यास त्रुटि, विस्तार करता है [ a b = 'a b' ]
    • x='a b'; [ "$x" = 'a b' ]समकक्ष
  • =

    • [[ ab = a? ]]: सच है, क्योंकि यह करता है पैटर्न मिलान (* ? [ जादू हैं)। ग्लोब वर्तमान निर्देशिका में फ़ाइलों में विस्तार नहीं करता है।
    • [ ab = a? ]: a? ग्लोब फैलता है। तो वर्तमान निर्देशिका में फ़ाइलों के आधार पर सच या गलत हो सकता है।
    • [ ab = a\? ]: झूठी, ग्लोब विस्तार नहीं
    • = तथा == दोनों में समान हैं [ तथा [[, परंतु == एक बैश विस्तार है।
    • printf 'ab' | grep -Eq 'a.': पॉज़िक्स ईआरई समकक्ष
    • [[ ab =~ 'ab?' ]]: झूठा, जादू खो देता है ''
    • [[ ab? =~ 'ab?' ]]: सच
  • =~

सिफ़ारिश करना

मैं हमेशा उपयोग करना पसंद करता हूं []

प्रत्येक के लिए POSIX समकक्ष हैं [[ ]] मैंने देखा है निर्माण।

यदि तुम प्रयोग करते हो [[ ]] आप:

  • पोर्टेबिलिटी खोना
  • पाठक को एक और बाश विस्तार की जटिलताओं को जानने के लिए मजबूर करें। [एक अजीब नाम के साथ सिर्फ एक नियमित आदेश है, कोई विशेष अर्थशास्त्र शामिल नहीं है।

61
2017-07-12 10:22



कैसे इस्तेमाल करे printf 'ab' | grep -Eq 'ab?' अंदर if [ … ]? - meeDamian
@meeDamian if ( printf 'ab' | grep -Eq 'a' ); then echo 'a'; fi। [] एक आदेश है जैसे grep। () उस आदेश पर इसकी आवश्यकता नहीं हो सकती है मुझे यकीन नहीं है: मैंने इसे इसलिए जोड़ा है |, इस बात पर निर्भर करता है कि कैसे बैश चीजों को पार करता है। अगर वहां नहीं था | मुझे यकीन है कि आप बस लिख सकते हैं if cmd arg arg; then। - Ciro Santilli 新疆改造中心 六四事件 法轮功
@meeDamian हाँ, कोई ज़रूरत नहीं है () ऐसा लगता है: stackoverflow.com/questions/8965509/... - Ciro Santilli 新疆改造中心 六四事件 法轮功
अच्छी सूची! यह भी देखें: wiki.ubuntu.com/... - radistao


मैनपेज के प्रासंगिक वर्गों के त्वरित पढ़ने के आधार पर, प्राथमिक अंतर यह प्रतीत होता है कि == तथा != ऑपरेटर एक शाब्दिक स्ट्रिंग के बजाय पैटर्न के खिलाफ मेल खाते हैं, और यह भी है कि =~ रेगेक्स तुलना ऑपरेटर।


4
2017-08-09 21:17





सिंगल ब्रैकेट अर्थात। [] एक सशर्त अभिव्यक्ति संलग्न करने के लिए POSIX खोल अनुपालन है।

डबल ब्रैकेट्स अर्थात। [[]] मानक POSIX संस्करण का एक उन्नत (या विस्तार) संस्करण है, यह बैश और अन्य शैल (zsh, ksh) द्वारा समर्थित है।

बैश में, संख्यात्मक तुलना के लिए हम उपयोग करते हैं eq, ne,lt तथा gtतुलना के लिए डबल ब्रैकेट के साथ हम उपयोग कर सकते हैं ==, !=, <, तथा > सचमुच।

  • [ परीक्षण कमांड के लिए समानार्थी है। भले ही यह खोल में बनाया गया हो, यह एक नई प्रक्रिया बनाता है।
  • [[ इसका एक नया उन्नत संस्करण है, जो एक कीवर्ड है, न कि एक कार्यक्रम।

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

[ var1 lt var2] #works
[ var1 < var2] #error: var2 No such file or directory 
[ var1 \< var2] #works with escape
[[ var1 < var2]] #works

3
2018-02-08 03:15