उदाहरण के लिए, निम्न कमांड काम नहीं करता है:
if [[-e xyz]]; then echo File exists;fi
ksh निम्नलिखित त्रुटि देता है
[[-e: command not found
क्या इसलिए कि "[[-" अस्पष्ट है?
उदाहरण के लिए, निम्न कमांड काम नहीं करता है:
if [[-e xyz]]; then echo File exists;fi
ksh निम्नलिखित त्रुटि देता है
[[-e: command not found
क्या इसलिए कि "[[-" अस्पष्ट है?
जवाबों:
सबसे सरल स्पष्टीकरण होगा, क्योंकि मैनुअल में ऐसा प्रतीत होता है जैसे [[ expression ]]
कि [[
और बीच expression
और बंद होने के लिए जगह होनी चाहिए ]]
। लेकिन निश्चित रूप से हम इसे और गहराई से देखने का प्रयास कर सकते हैं। शेल में कुछ जटिल व्याकरण होते हैं और "शब्द विभाजन" की अवधारणा पर बहुत अधिक भरोसा करते हैं। विशेष रूप से, ksh (1) मैनुअल स्टेट्स:
खोल अपने इनपुट को शब्दों में तोड़कर पार्स करना शुरू कर देता है। शब्द, जो वर्णों के अनुक्रम हैं, को निर्विवाद श्वेत-स्थान वाले वर्णों (स्थान, टैब और न्यूलाइन) या मेटा-वर्णों (<,>,;,;, और (और)) द्वारा सीमांकित किया जाता है। परिसीमन शब्दों के अलावा, रिक्त स्थान और टैब को नजरअंदाज कर दिया जाता है, जबकि नए सिरे आमतौर पर आदेशों का परिसीमन करते हैं।
इसलिए जैसा कि नियमावली में कहा गया है, वर्णों के अनुक्रम को [[-e
एक शब्द शब्द माना जाता है। ksh
बिल्ट-इन और विशेष ऑपरेटरों (जैसे for
या while
) की सूची में इस तरह के कमांड की तलाश करेंगे , फिर एक बाहरी कमांड की तलाश करेंगे - और वॉइलिया - कोई नहीं मिला, इसलिए कमांड के बारे में कोई त्रुटि संदेश नहीं मिला।
इस मामले [[
में विशेष मेटा-कैरेक्टर भी नहीं हैं। अगर वे थे, -e
भाग में [[-e
एक खोल शब्द, नहीं करने के लिए एक तर्क पर विचार किया जाएगा [[
ही। हालाँकि, [[
यौगिक कमांड के रूप में वर्णित है, और मैनुअल निम्नलिखित कहता है:
कंपाउंड कमांड निम्न आरक्षित शब्दों का उपयोग करके बनाई गई हैं - इन शब्दों को केवल तभी पहचाना जाता है यदि वे अयोग्य हैं और यदि उन्हें कमांड के पहले शब्द के रूप में उपयोग किया जाता है (यानी, वे पैरामीटर असाइनमेंट या पुनर्निर्देशन से पहले नहीं हो सकते हैं):
इसलिए [[
कंपाउंड कमांड के रूप में पहचाने जाने के लिए , इसे कमांड या कमांड लिस्ट का पहला शब्द होना चाहिए, जो "शब्द" की पिछली परिभाषा से तात्पर्य है कि इसे स्पेस, टैब या अन्य से अलग करना होगा। शब्द / तर्क।
आपने टिप्पणियों में पूछा है : "" [["पैटर्न मिलते ही पार्सर क्यों नहीं रुक सकता, और यह मानते हैं कि सशर्त कमांड की शुरुआत के रूप में?" संक्षिप्त उत्तर शायद इसलिए है क्योंकि 1) [
सिंटैक्स का प्रभाव क्योंकि यह मूल रूप से एक बाहरी कमांड था, और POSIX मानक अनुपालन के लिए आज भी बाहरी कमांड के रूप में मौजूद है, और 2) क्योंकि शेल पार्सर बनाया गया है। शेल पार्सर अन्य गैर-स्थान सीमांकित विशेष वर्णों को पहचान सकता है: echo $((2+2))
और (echo foobar)
पूरी तरह से ठीक काम करता है। हो सकता है कि भविष्य में जब ksh
विकास फिर से शुरू हो या कोई कांटा या क्लोन (जैसे mksh
या pdksh
) प्रतीत हो, तो कोई अंतरिक्ष में कम-से-कम सिंटैक्स लागू करेगा [[-e
।
[[
एक "आरक्षित शब्द" कहा जाता है ( शेल कमांड लैंग्वेज का खंड 2.9 देखें )। POSIX परिभाषा के अनुसार, आरक्षित शब्द को रिक्त स्थान द्वारा सीमांकित किया जाना है। इसके विपरीत (
एक ऑपरेटर है, और मानक 2.9 में मानक राज्य "प्रतिनिधित्व में कुछ स्थानों पर टोकन के बीच रिक्ति शामिल है जहां <blank>
एस आवश्यक नहीं होगा (जब टोकन में से एक ऑपरेटर होता है")। संबंधित चर्चा देखें: POSIX शेल व्याकरण: ब्रेस ग्रुप को पहले स्थान की आवश्यकता क्यों है लेकिन सब्सक्राइब नहीं होता है?char
एक कीवर्ड है लेकिन आप अभी भी लिख नहीं सकते हैं charsomeletter = 'A';
और पार्सर को देखने के बाद बंद होने की उम्मीद कर सकते हैं char
।
i--<=++j
, और संकलक के रूप में पार्स करने में कोई समस्या नहीं है i -- <= ++ j
।
_
) की अनुमति देते हैं । Ksh के पास (
एक ऑपरेटर के रूप में है , और (echo hello)
पर्स के रूप में ( echo hello )
। यह है if
, {
, [[
, और अन्य कीवर्ड , और ifx
, {x
और [[x
हर एक टोकन कर रहे हैं - कैसे की तरह charsomeletter
एक सी टोकन है। इसके विपरीत, (x
ksh में एक अयोग्य दो टोकन हैं - जैसे कि i--
C. में दो टोकन कैसे हैं । वैचारिक रूप से इसका अर्थ यह भी है कि ऑपरेटर का बॉर्न-शैली के गोले (जैसे ksh) और C. के बीच अंतर होता है, लेकिन पीटर ए। श्नाइडर ने बताया वास्तविक शाब्दिक समानता।
यह नोट करना महत्वपूर्ण है कि [
एक कमांड क्या है , और [[
bash और ksh में शेल कीवर्ड पर आधारित है [
।
[[
के लिए एक समान तरीके से उपयोग किया जाता है [
। कभी-कभी आप व्यवहार में कोई बदलाव न करने के [
]
साथ भी बदल सकते [[
]]
हैं। [
किसी भी आदेश के साथ , कमांड और उसके तर्कों के बीच एक स्थान अनिवार्य है। वही लागू होता है [[
।
हमारे पास ही हुआ करती थी /usr/bin/[
। अब अधिकांश गोले [
दक्षता के लिए बनाए गए हैं - लेकिन सिंटैक्स समान है। प्रदान करने वाले गोले में [[
, यह एक अधिक बहुमुखी विकल्प के रूप में कार्य करता है [
।
यहाँ [
बैश में वर्णन है :
$ 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
उस पर और भी अधिक विवरण देंगे। आप इसकी तुलना कर सकते हैं help [[
।
बाहरी कमांड के लिए एक मैन पेज भी है [
( man \[
)।
के मामले में
if [[-e
[
है और न ही [[
कोई आदेश, वहाँ है। पूरा शब्द [[-e
है।if [[-e
इसे सत्य / असत्य की परीक्षा बनाता है। तो क्या एक कमांड [[-e
मौजूद है? क्या इसलिए कि "[[-" अस्पष्ट है?
हाँ। याँ नहीं। [[-e
यह क्या है: कुछ भी नहीं है कि शेल समझ में आता है तो यह मानता है कि यह अपना आदेश है। ;-)
[[-e
एक संभावित वैध (यदि अजीब दिखने वाला) कमांड नाम है।
अंतरिक्ष एक अपराधी है और आवश्यक है। जैसा कि आप देख सकते हैं shellcheck
:
$ shellcheck gmail-browse-msgs-algorithm.sh
In gmail-browse-msgs-algorithm.sh line 847:
[[$Today != "${DaysArr[ i + DAY_DELETED_ON_NDX ]}" ]] && continue
^-- SC1035: You need a space after the [[ and before the ]].
(Ksh और bash दोनों समर्थन करते हैं [[
और बिना स्पेस के काम नहीं करते। शेल्चेक बिल्कुल उसी ksh और bash स्क्रिप्ट के साथ आउटपुट देता है, जिसमें छोटी गाड़ी लाइन होती है।)
क्यों अपराधियों की जरूरत है टोकन और lexicons के साथ क्या करना है ।
ksh
प्रश्न में शेल के बारे में पूछा। बैश उधार लेता [[
से ऑपरेटर ksh
और इस सवाल का उनके व्यवहार के समान है, लेकिन वहाँ के रूप में के बीच कुछ महत्वपूर्ण अंतर है मैं मान्यताओं के सावधान रहना होगा ksh
और bash
व्यवहार और आंतरिक। यह सिर्फ इसलिए है क्योंकि शेलचेक बैश स्क्रिप्ट पर काम करता है, यह आवश्यक रूप से ksh स्क्रिप्ट के लिए उपयुक्त उपकरण नहीं हो सकता है। अलग-अलग गोले के पास जाने के लिए बस कुछ ध्यान में रखें
[[
अंतर्निहित नियमों को उजागर करने के लिए कवच का उपयोग करके अवसरवादी हो रहा था । मैं किसी भी तरह से जिक्र नहीं कर रहा था कि ksh
एक शेल था जो shellcheck
त्रुटियों को पा सकता था। मुझे आशा है कि अन्य लोग सराहना करते हैं ksh
और bash
दो अलग-अलग व्याख्याकार हैं। उस उल्लेख के लिए धन्यवाद। यह भी ध्यान देने योग्य [[
है [
कि एक बाहरी कमांड में बनाया गया एक बैश है।
[
में यह बिल्ट-इन bash :) manpages.ubuntu.com/manpages/bionic/man7/bash-builtins.7.html भी है, लेकिन आप बहुत दूर नहीं हैं - [
या test
बाहरी कमांड होना आवश्यक है। मूल बॉर्न शेल के दिनों [
में वास्तव में एक बाहरी आदेश था, और अभी भी आजकल के रूप में मौजूद है /usr/bin/[
क्योंकि POSIX को बाहरी कमांड pubs.opengroup.org/onlinepubs/009695399/utilities/test.html की आवश्यकता होती है क्योंकि कुछ POSIX द्वारा आवश्यक हैं। में निर्मित किया जा pubs.opengroup.org/onlinepubs/009695399/idx/sbi.html अंतर्निहित [
क्षमता के लिए है
ksh
; हैशबैंग का उपयोग करें या -s ksh
। Btw, ksh और bash में [[
"बिल्ट इन" है, लेकिन यह एक कीवर्ड है , इसके विपरीत [
, जो एक शेल बिलिन है । (ksh whence -v [ [[
:; bash type [ [[
:) बिल्ट और एक्सटर्नल कमांड सिंटैक्टिक रूप से एक जैसे होते हैं। [[
इससे अलग एक तरीका यह [
है कि वह [[
अपने तर्कों में कुछ विस्तार को दबाता है, जो कि वह बिलियन के रूप में {
नहीं कर सकता है - जितना समूहन नहीं कर सकता था वह एक बिलिन था। यह हो सकता है क्यों {x
(या [[x
) एक टोकन अजीब लग रहा है। मुझे लगता है कि यह कहना सही है कि बिलिन और कीवर्ड लेक्सिक हैं, लेकिन सिंटैक्टिक रूप से समान नहीं हैं । @SergiyKolodyazhnyy
[[
एक बाहरी आदेश हो सकता है! यही है, यह एक कार्यक्रम हो सकता है और सीधे आपके शेल द्वारा समर्थित कुछ सिंटैक्स नहीं। स्पेस-कम सिंटैक्स का समर्थन करना संभव होगा, ksh
लेकिन यह बाहरी के साथ सिस्टम पर विफल होगा, [[
इसलिए अनुकूलता के लिए आवश्यक स्थान रखना बेहतर है।
[[
उदाहरण के लिए बिजीबॉक्स एक बाहरी कमांड के रूप में प्रदान कर रहा है ।
चूंकि [[-e
शेल विस्तार में भाग ले सकते हैं (इसका उपयोग किया जा सकता है
echo [[-e]*
सभी फ़ाइलों को सूचीबद्ध करने के लिए [
और बीच में एक अक्षर के साथ शुरू होने वाली सूची e
), यह एक पूर्ण गड़बड़ी होगी यदि [
और ]
विशेष वर्ण सामान्य व्हाट्सएप-शासित शब्द विभाजन में भाग नहीं ले रहे थे।
[[
एक कीवर्ड है - संभवतः शेल के पार्स ट्री के लिए आवश्यक है कि कीवर्ड को