سؤال ما الفرق بين الأقواس المربعة المزدوجة والمجمعة في bash؟


أنا فقط أتساءل ما الفرق بالضبط بين

[[ $STRING != foo ]]

و

[ $STRING != foo ]

هو ، بصرف النظر عن أن هذا الأخير متوافق مع posix ، موجود في sh والأول هو امتداد موجود في bash.


347
2017-08-09 21:11


الأصل


إذا كنت تتساءل أيضًا عن عدم استخدام الأقواس على الإطلاق ، على سبيل المثال ، في سياق if بيان ، انظر mywiki.wooledge.org/BashPitfalls#if_.5Bgrep_foo_myfile.5D - Kev
أيضًا ، من مستندات Ubuntu: wiki.ubuntu.com/... - radistao


الأجوبة:


هناك عدة اختلافات. في رأيي ، بعض من أهمها:

  1. [ هو مدمج في باش والعديد من الأصداف الحديثة. مدمج [ مشابه ل test مع المتطلبات الإضافية للإغلاق ]. الموديلات [ و test تقليد الوظيفة /bin/[ و /bin/test جنبا إلى جنب مع قيودها بحيث تكون متوافقة مع البرامج النصية. لا تزال الملفات التنفيذية الأصلية موجودة بشكل أساسي من أجل توافق POSIX والتوافق مع الإصدارات السابقة. تشغيل الأمر type [ في باش يدل على ذلك [ يتم تفسيره على أنه مدمج افتراضيًا. (ملحوظة: which [ يبحث فقط عن الملفات التنفيذية على مسار وهو ما يعادل type -p [)
  2. [[ ليست متوافقة ، لن تعمل بالضرورة مع أي شيء /bin/sh نقاط ل. وبالتالي [[ هو الخيار Bash / Zsh / Ksh الأكثر حداثة.
  3. لان [[ بنيت في الصدفة وليس لديها متطلبات قديمة ، لا داعي للقلق حول تقسيم الكلمات على أساس IFS متغير للتلاعب على المتغيرات التي تقيم لسلسلة مع مسافات. لذلك ، لا تحتاج إلى وضع المتغير في علامات اقتباس مزدوجة.

بالنسبة للجزء الاكبر ، والباقي هو مجرد بعض الجمل أجمل. للاطلاع على مزيد من الاختلافات ، أوصيك بهذا الرابط لإجابات الأسئلة الشائعة: ما هو الفرق بين الاختبار ، [و [؟. في الواقع ، إذا كنت جادًا حول البرمجة النصية bash ، فإنني أنصحك بقراءة البرنامج بأكمله ويكي، بما في ذلك الأسئلة الشائعة ، المزالقوالدليل. قسم الاختبار من قسم الدليل يشرح هذه الاختلافات كذلك ، ولماذا يفكر المؤلف (المؤلفون) [[ هو خيار أفضل إذا كنت لا داعي للقلق بشأن كونك محمولًا. الأسباب الرئيسية هي:

  1. لا داعي للقلق حول اقتباس الجانب الأيسر من الاختبار بحيث يتم قراءته كمتغير.
  2. ليس عليك الهرب أقل من وأكبر من < > مع الخطوط المائلة العكسية لكي لا يتم تقييمها كإعادة توجيه مدخلات ، والتي يمكن أن تفسد بعض الأشياء عن طريق الكتابة فوق الملفات. هذا يعود مرة أخرى إلى [[ كونه مدمج. إذا كان [(الاختبار) برنامجًا خارجيًا ، فسيتعين على shell إجراء استثناء في طريقة تقييمه < و > فقط اذا /bin/test يتم استدعاؤها ، والتي لن تكون ذات معنى.

262
2017-08-09 21:56



شكراً ، كان الرابط إلى الأسئلة الشائعة عن bash هو ما كنت أبحث عنه (لم أكن أعرف عن هذه الصفحة ، شكرًا). - 0x89
قمت بتحرير مشاركتك بهذه المعلومات ، ولكن [تم تنفيذ الاختبار كـ builtin. تم تصميم الموديلات لتحل محل / bin / [و / bin / test ولكنها تحتاج إلى إعادة إنتاج قيود الثنائيات أيضًا. يتحقق الأمر 'type [' من أنه تم استخدام المضمن. "التي" تبحث فقط عن الملفات التنفيذية على PATH وتعادل "type -P [" - klynch


بالمختصر:

[هو باش مدمج

[] هي [باش] الكلمات الدالة

الكلمات الدالة: الكلمات الرئيسية تشبه إلى حد كبير المداخل ، ولكن الاختلاف الرئيسي هو أن قواعد التحليل الخاصة تنطبق عليها. على سبيل المثال ، يكون [bash builtin ، بينما [[هي كلمة أساسية في bash. وتستخدم كلاهما لاختبار الاشياء ، ولكن بما أن [[هي كلمة أساسية وليست مبنية ، فإنها تستفيد من بعض قواعد التحليل الخاصة التي تجعل الأمر أسهل بكثير:

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

يقوم المثال الأول بإرجاع خطأ لأن bash يحاول إعادة توجيه الملف b إلى الأمر [a]. المثال الثاني يفعل ما تتوقعه. الحرف <لم يعد له معنى خاص لمشغل إعادة توجيه الملف.

مصدر: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments


110
2017-12-29 19:42



[ هو أمر shell POSIX ؛ لا تحتاج إلى أن تبنى. ] هو مجرد حجة التي يبحث عنها هذا الأمر ، بحيث يتم موازنة بناء الجملة. الأمر مرادف لـ test ماعادا هذا test لا تبحث عن الإغلاق ]. - Kaz
انظر هنا: pubs.opengroup.org/onlinepubs/009695399/utilities/test.html - Kaz


فروق السلوك

تم اختبارها في Bash 4.3.11:

  • ملحق POSIX مقابل Bash:

  • القيادة العادية مقابل السحر

    • [ هو مجرد أمر عادي باسم غريب.

      ] هو مجرد حجة [ يمنع المزيد من استخدام الحجج.

      Ubuntu 16.04 لديه بالفعل برنامج قابل للتنفيذ في /usr/bin/[ المقدمة من coreutils ، ولكن النسخة bash المضمنة تأخذ الأسبقية.

      لا يتم تغيير أي شيء في الطريقة التي يوزع بها باش الأمر.

      خاصه، < هو إعادة التوجيه ، && و || تسلسل أوامر متعددة ، ( ) يولد subshells ما لم يفلت من قبل \، ويتم توسيع كلمة كالمعتاد.

    • [[ X ]] هو بناء واحد يجعل X يتم تحليلها بطريقة سحرية. <، &&، || و () يعاملون بشكل خاص ، وقواعد تقسيم الكلمات مختلفة.

      هناك أيضا مزيد من الاختلافات مثل = و =~.

    في باشيسي: [ هو أمر مدمج ، و [[ هي الكلمة الرئيسية: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword

  • <

  • && و ||

    • [[ a = a && b = b ]]: صحيح ومنطقي و
    • [ a = a && b = b ]: خطأ في بناء الجملة، && تم تحليلها كفاصل فقرة أمر AND 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? ]]: صحيح ، لأنه يفعل نمط مطابقة (* ? [ هي السحر). لا يتمدد glob إلى الملفات في الدليل الحالي.
    • [ ab = a? ]: a? يتوسع العالم. قد يكون ذلك صحيحًا أو خطأ وفقًا للملفات الموجودة في الدليل الحالي.
    • [ ab = a\? ]: كاذبة ، وليس توسيع glob
    • = و == هي نفسها في كليهما [ و [[، لكن == هو امتداد باش.
    • printf 'ab' | grep -Eq 'a.': POSIX ERE مكافئ
    • [[ ab =~ 'ab?' ]]: كاذبة ، يفقد السحر مع ''
    • [[ ab? =~ 'ab?' ]]: صحيح
  • =~

    • [[ ab =~ ab? ]]: صحيح ، POSIX تمديد التعبير العادي مباراة، ? لا يتوسع العالم
    • [ a =~ a ]: خطأ في بناء الجملة
    • printf 'ab' | grep -Eq 'ab?': ما يعادل POSIX

توصية

أنا أفضل أن استخدم دائما [].

هناك مكافئات POSIX لكل [[ ]] بناء رأيته.

إذا كنت تستخدم [[ ]] أنت:

  • تفقد قابلية
  • يجبر القارئ على معرفة تعقيدات تمديد باش أخرى. [هو مجرد أمر عادي مع اسم غريب ، لا تشارك دلالات خاصة.

63
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


استنادًا إلى قراءة سريعة للأقسام ذات الصلة من الصفحة الرئيسية ، يبدو أن الاختلاف الأساسي هو أن == و != تتطابق المشغلات مع نمط ، بدلا من سلسلة حرفية ، وأيضا أن هناك =~ مشغل المقارنة regex.


4
2017-08-09 21:17





قوس واحد أي [] هو متوافق مع POSIX shell لإرفاق تعبير شرطي.

أقواس مزدوجة أي [[]] هو نسخة محسنة (أو ملحق) لإصدار POSIX القياسي ، وهو مدعوم من bash وأصداف أخرى (zsh و ksh).

في bash ، للمقارنة الرقمية التي نستخدمها 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