एक सरलीकृत कारण एक चरित्र का अस्तित्व है space:।
ब्रेस एक्सपैंशन (अन-कोटेड) स्पेस को प्रोसेस नहीं करते हैं।
एक {...}
सूची की जरूरत है (संयुक्त राष्ट्र) रिक्त स्थान।
अधिक विस्तृत जवाब यह है कि शेल एक कमांड लाइन को कैसे पार करता है ।
कमांड लाइन को पार्स (समझने) के लिए पहला चरण इसे भागों में विभाजित करना है।
ये भाग (आमतौर पर शब्द या टोकन कहा जाता है) लिंक से प्रत्येक मेटा-चरित्र पर एक कमांड लाइन को विभाजित करने के परिणामस्वरूप होता है :
- मेटा-वर्णों के निश्चित सेट द्वारा अलग किए गए टोकन में कमांड को विभाजित करता है: SPACE, TAB, NEWLINE, (,), <,>, |, &, &। टोकन के प्रकारों में शब्द, कीवर्ड, I / O पुनर्निर्देशक और अर्धविराम शामिल हैं।
मेटा-वर्ण: spacetabenter;,<>|और &।
विभाजन के बाद, शब्द एक प्रकार के हो सकते हैं (जैसा कि शेल द्वारा समझा जाता है):
- आदेश पूर्व-असाइनमेंट:
LC=ALL ...
- आदेश
LC=ALL echo
- तर्क
LC=ALL echo "hello"
- पुनर्निर्देशन
LC=ALL echo "hello" >&2
ब्रेस विस्तार
केवल अगर एक "ब्रेस स्ट्रिंग" (रिक्त स्थान या मेटा-वर्ण के बिना) एक एकल शब्द है (जैसा कि ऊपर वर्णित है) और उद्धृत नहीं किया गया है , यह "ब्रेस विस्तार" के लिए एक उम्मीदवार है। बाद में आंतरिक संरचना पर अधिक जांच की जाती है।
इस प्रकार, यह: {ls,-l}
"ब्रेस विस्तार" के रूप में अर्हता प्राप्त करता है ls -l
, या तो first word
या argument
(बाश में, zsh अलग है)।
$ {ls,-l} ### executes `ls -l`
$ echo {ls,-l} ### prints `ls -l`
लेकिन यह नहीं होगा {ls ,-l}
:। बैश spaceदो शब्दों के रूप में लाइन को विभाजित करेगा और पार्स करेगा : {ls
और ,-l}
जो ट्रिगर करेगा command not found
(तर्क ,-l}
खो गया है):
$ {ls ,-l}
bash: {ls: command not found
आपकी रेखा: दो मेटा-पात्रों और के {ls;echo hi}
कारण "ब्रेस विस्तार" नहीं बनेगी ।;space
इसे इस तीन भागों में तोड़ा जाएगा: {ls
नई आज्ञा echo
hi}
:। यह समझें कि ;एक नई कमांड की शुरुआत को ट्रिगर करता है। कमांड {ls
नहीं मिलेगी, और अगला कमांड प्रिंट करेगा hi}
:
$ {ls;echo hi}
bash: {ls: command not found
hi}
यदि इसे किसी अन्य कमांड के बाद रखा जाता है, तो यह वैसे भी एक नया कमांड शुरू करेगा ;:
$ echo {ls;echo hi}
{ls
hi}
सूची
"कंपाउंड कमांड" में से एक "ब्रेस लिस्ट" (मेरे शब्द) है { list; }
:।
जैसा कि आप देख सकते हैं, यह रिक्त स्थान और एक समापन के साथ परिभाषित किया गया है ;
।
रिक्त स्थान और ;क्योंकि दोनों की जरूरत है {
और }
कर रहे हैं "सुरक्षित शब्द "।
और इसलिए, शब्दों के रूप में पहचाने जाने के लिए, मेटा-पात्रों (लगभग हमेशा:) से घिरा होना चाहिए space।
जैसा कि लिंक किए गए पृष्ठ के बिंदु 2 में वर्णित है
- प्रत्येक कमांड के पहले टोकन को यह देखने के लिए चेक करता है कि क्या यह ...., {, या (, तो कमांड वास्तव में एक कंपाउंड कमांड है।
आपका उदाहरण: {ls;echo hi}
सूची नहीं है।
इसे एक समापन ;और एक स्थान (कम से कम) के बाद की आवश्यकता है {। अंतिम }को समापन द्वारा परिभाषित किया गया है ;।
यह एक सूची है { ls;echo hi; }
। और यह { ls;echo hi;}
भी है (कम आमतौर पर इस्तेमाल किया जाता है, लेकिन वैध) (मदद के लिए धन्यवाद @choroba)।
$ { ls;echo hi; }
A-list-of-files
hi
लेकिन तर्क के रूप में (शेल को अंतर पता है) कमांड के लिए, यह एक त्रुटि को ट्रिगर करता है:
$ echo { ls;echo hi; }
bash: syntax error near unexpected token `}'
लेकिन सावधान रहें कि आपको क्या विश्वास है कि शेल पार्स कर रहा है:
$ echo { ls;echo hi;
{ ls
hi
{
एक कमांड सूची के रूप में व्याख्या की जा सकती है यदि यह एक कमांड की शुरुआत में और अन्यथा ब्रेस विस्तार के रूप में प्रकट होता है, लेकिन मुझे यकीन नहीं है।