जवाबों:
के बीच का अंतर [[ … ]]
और [ … ]
ज्यादातर सिंगल या डबल ब्रैकेट का उपयोग करके कवर किया जाता है - बैश । महत्वपूर्ण रूप से, [[ … ]]
विशेष वाक्यविन्यास है, जबकि [
एक कमांड के लिए एक मजाकिया दिखने वाला नाम है। [[ … ]]
अंदर क्या है, [ … ]
इसके लिए विशेष वाक्यविन्यास नियम नहीं हैं।
वाइल्डकार्ड की अतिरिक्त शिकन के साथ, यहाँ कैसे [[ $a == z* ]]
मूल्यांकन किया गया है:
[[ … ]]
सशर्त अभिव्यक्ति के चारों ओर सशर्त निर्माण है $a == z*
।==
बाइनरी ऑपरेटर है, ऑपरेंड्स के साथ $a
और z*
।a
।==
ऑपरेटर का मूल्यांकन करें : परीक्षण करें यदि चर का मान a
पैटर्न से मेल खाता है z*
।[ $a == z* ]
इसका मूल्यांकन कैसे किया जाता है:
[
तर्क शब्द का मूल्यांकन द्वारा गठित साथ आदेश $a
, ==
, z*
, ]
।$a
चर के मान में विस्तार करें a
।a
6-चरित्र स्ट्रिंग है foo b*
(उदाहरण के द्वारा प्राप्त a='foo b*'
) और वर्तमान निर्देशिका है (में फ़ाइलों की सूची bar
, baz
, qux
, zim
, zum
), तो विस्तार का परिणाम शब्द के निम्नलिखित सूची है: [
, foo
, bar
, baz
, ==
, zim
, zum
, ]
।[
पिछले चरण में प्राप्त मापदंडों के साथ कमांड चलाएं ।
[
कमांड एक सिंटैक्स त्रुटि की शिकायत करता है और स्थिति 2 लौटाता है।नोट: [[ $a == z* ]]
चरण 3 में, मान का a
विभाजन और फ़ाइल नाम का निर्माण नहीं होता है, क्योंकि यह एक ऐसे संदर्भ में है जहाँ एक शब्द की अपेक्षा की जाती है (सशर्त ऑपरेटर के बाएं हाथ का तर्क ==
)। ज्यादातर मामलों में, यदि कोई शब्द उस स्थिति में समझ में आता है, तो चर विस्तार ऐसा व्यवहार करता है जैसे वह दोहरे उद्धरणों में करता है। हालाँकि, उस नियम का एक अपवाद है: [[ abc == $a ]]
यदि a
वाइल्डकार्ड में मान समाहित है, तो a
वाइल्डकार्ड पैटर्न से मिलान किया जाता है। उदाहरण के लिए, यदि मान a
है a*
तो [[ abc == $a ]]
सच है (क्योंकि मैचों *
के निर्विवाद विस्तार से आने वाला वाइल्डकार्ड ) गलत है (क्योंकि साधारण चरित्र है)$a
*
[[ abc == "$a" ]]
*
के उद्धृत विस्तार से $a
मेल नहीं खाता bc
)। अंदर [[ … ]]
, डबल कोट कोई फर्क नहीं है, स्ट्रिंग मिलान ऑपरेटरों के दाएँ हाथ की ओर पर छोड़कर ( =
, ==
, !=
और =~
)।
[
test
कमांड के लिए एक उपनाम है । यूनिक्स संस्करण 6 में एक if
कमांड था, लेकिन वर्जन 7 (1979) नए बॉर्न शेल के साथ आया, जिसमें कुछ प्रोग्रामिंग कंस्ट्रक्शन थे, जिनमें अगर-तब-और-एलिफ-फाई कंस्ट्रक्शन भी शामिल था, और यूनिक्स वर्जन 7 में एक test
कमांड जोड़ा गया था, जो ज्यादातर काम करता था "परीक्षण" जो if
पुराने संस्करणों में कमांड द्वारा किए गए थे ।
[
को एक उर्फ बनाया गया था test
और दोनों को यूनिक्स सिस्टम III (1981) में शेल में बनाया गया था । हालांकि यह ध्यान दिया जाना चाहिए कि कुछ यूनिक्स वेरिएंट के पास [
बहुत बाद तक एक कमांड नहीं थी ( 2000 के दशक के शुरुआती दिनों तक कुछ बीएसडी पर जहां sh
अल्मक्विस्ट शेल पर आधारित है (एक बेसिनtest
हमेशा ash
's स्रोत में शामिल किया गया है , लेकिन उन पर) बीएसडी (यह शुरुआत में अक्षम था))।
ध्यान दें कि test
उर्फ [
"परीक्षण" करने के लिए एक कमांड है, कोई भी असाइनमेंट नहीं है जो कि कमांड करता है, इसलिए एक असाइनमेंट और समानता ऑपरेटर के बीच अंतर करने का कोई कारण नहीं है, इसलिए समानता ऑपरेटर है =
। ==
केवल कुछ हालिया कार्यान्वयनों द्वारा समर्थित है [
(और इसके लिए केवल एक उपनाम है =
)।
क्योंकि [
एक कमांड से ज्यादा कुछ नहीं है, इसे उसी तरह से पार्स किया जाता है जैसे शेल द्वारा किसी अन्य कमांड को।
विशेष रूप से, आपके उदाहरण में $a
, क्योंकि इसे उद्धृत नहीं किया गया है, शब्द विभाजन के सामान्य नियमों के अनुसार कई शब्दों में विभाजित किया जाएगा, और प्रत्येक शब्द फ़ाइलनाम पीढ़ी उर्फ ग्लोबिंग से गुजरना होगा जिसके परिणामस्वरूप संभवतः अधिक शब्द होंगे, उनमें से प्रत्येक शब्द जिसके परिणामस्वरूप था [
कमांड के लिए एक अलग तर्क ।
इसी तरह, z*
वर्तमान निर्देशिका में फ़ाइल नाम की सूची के साथ विस्तारित किया जाएगा z
।
तो उदाहरण के लिए, अगर $a
है b* = x
, और देखते हैं z1
, z2
, b1
और b2
वर्तमान निर्देशिका में फ़ाइलों को, [
आदेश 9 तर्क मिलेगा: [
, b1
, b2
, =
, x
, ==
, z1
, z2
और ]
।
[
एक सशर्त अभिव्यक्ति के रूप में अपने तर्कों को पार्स करता है। वे 9 तर्क एक वैध सशर्त अभिव्यक्ति तक नहीं जोड़ते हैं, इसलिए यह संभवतः एक त्रुटि लौटाएगा।
[[ ... ]]
निर्माण कॉर्न खोल द्वारा पेश किया गया था शायद आसपास 1988 ksh86a
से 1987 में यह नहीं था, जबकि ksh88
यह शुरू से ही था।
बगल में ksh (सभी कार्यान्वयन), [[...]]
भी bash (संस्करण 2.02 के बाद से) और zsh द्वारा समर्थित है, लेकिन सभी तीन कार्यान्वयन अलग-अलग हैं और एक ही शेल के प्रत्येक संस्करण के बीच अंतर हैं, हालांकि परिवर्तन आम तौर पर पिछड़े संगत हैं (एक उल्लेखनीय है जो बैश है) =~
ऑपरेटर जो एक निश्चित संस्करण के बाद कुछ लिपियों को तोड़ने के लिए जाना जाता है जब इसका व्यवहार बदल जाता है)। [[...]]
POSIX, या Unix या Linux (LSB) द्वारा निर्दिष्ट नहीं है। इसे कुछ बार शामिल करने पर विचार किया गया है, लेकिन इसे शामिल नहीं किया गया है क्योंकि प्रमुख शेल द्वारा समर्थित इसकी सामान्य कार्यक्षमता पहले से ही [
कमांड और case-in-esac
निर्माण द्वारा कवर की गई है ।
पूरा [[ ... ]]
निर्माण एक कमांड बनाता है। यही है, इसकी एक निकास स्थिति है (जो इसकी सबसे महत्वपूर्ण संपत्ति है क्योंकि यह सशर्त अभिव्यक्ति का मूल्यांकन करने का परिणाम है), आप इसे किसी अन्य कमांड पर पाइप कर सकते हैं (हालांकि यह उपयोगी नहीं होगा), और आम तौर पर जहाँ भी आप इसका उपयोग करते हैं किसी अन्य कमांड का उपयोग करें (केवल शेल के अंदर, क्योंकि यह शेल कंस्ट्रक्शन है) लेकिन इसे सामान्य साधारण कमांड की तरह पार्स नहीं किया जाता है। अंदर क्या है इसे सशर्त अभिव्यक्ति के रूप में खोल दिया गया है और शब्द विभाजन और फ़ाइल नाम पीढ़ी के सामान्य नियम अलग-अलग लागू होते हैं।
[[ ... ]]
==
शुरू से जानता है और =
1 के बराबर है । Ksh का एक गलती है, हालांकि है (और भ्रम और कई कीड़े खड़ी कर रहा है) है कि =
और ==
एक समानता ऑपरेटर लेकिन एक पैटर्न मिलान ऑपरेटर (हालांकि नहीं कर रहे हैं मिलान पहलू के हवाले से साथ लेकिन यह स्पष्ट नहीं कि नियमों खोल करने के लिए खोल से अलग से निष्क्रिय किया जा सकता)।
आपके कोड के ऊपर [[ $a == z* ]]
, शेल सामान्य लोगों के समान नियमों में कई टोकन में पार्स करेगा, इसे एक पैटर्न मिलान तुलना के रूप में पहचानता है, चर z*
की सामग्री के खिलाफ मिलान करने के लिए एक पैटर्न के रूप में a
मानता है।
आम तौर पर, अपने आप को पैर में गोली मारना कठिन [[ ... ]]
होता है क्योंकि यह [
कमांड के साथ होता है । लेकिन कुछ नियम जैसे
-a
या -o
ऑपरेटर का उपयोग कभी न करें (कई [
कमांड &&
और ||
शेल ऑपरेटर का उपयोग करें)[
POSIX गोले के साथ विश्वसनीय बनाओ ।
[[...]]
अलग-अलग गोले में अतिरिक्त संचालकों का समर्थन करते हैं -nt
, जैसे कि रेग्जिप मिलान ऑपरेटरों ... लेकिन सूची और व्यवहार शेल से शेल और संस्करण से भिन्न होता है।
इसलिए जब तक आप यह नहीं जानते कि आपकी स्क्रिप्ट किस शेल और न्यूनतम संस्करण की व्याख्या करेगी, तो यह शायद मानक [
कमांड के साथ रहना सुरक्षित है ।
1 एक अपवाद: [[...]]
संस्करण में बैश करने के लिए जोड़ा गया था 2.02
। जब तक 2.03
इसे बदल दिया गया था, तब तक यह [[ x = '?' ]]
सच [[ x == '?' ]]
होगा जबकि झूठे वापस आ जाएगा। यह उद्धृत करना है कि =
उन संस्करणों में ऑपरेटर का उपयोग करते समय पैटर्न मिलान को रोकना नहीं था , लेकिन उपयोग करते समय किया ==
।
[ '!' = foo -o a = a ]
में bash
उदाहरण के लिए।
दोनों का उपयोग अभिव्यक्तियों के मूल्यांकन के लिए किया जाता है और [[POSIX पुराने बोर्न शेल के साथ काम नहीं करेगा और [[पैटर्न मिलान और रेगेक्स का भी समर्थन करता है। उदाहरण इनका प्रयास करें
[ $n -eq 0 -a $y -eq 0 ] && echo "Error" || echo "Ok"
[[ $n -eq 0 && $y -eq 0 ]] && echo "Error" || echo "Ok"
[[...]]
केवल कुछ गोले के कुछ संस्करणों में regexps का समर्थन करता है, जैसे कुछ संस्करण [
regexp मिलान का समर्थन करते हैं। गणितज्ञ तुलना के लिए, उन गोले में जो समर्थन करते हैं [[
, आप बल्कि लिखेंगे(( n == 0 && y == 0))