POSIX खोल: क्या `$` अपना विशेष अर्थ खो देता है यदि यह एक शब्द में अंतिम वर्ण है?


17

जब मैं दौड़ता हूं तो राख, पानी का छींटा और बैश पर

$ echo ab$

यह लौट आता है

ab$

क्या यह व्यवहार POSIX द्वारा निर्दिष्ट किया गया है या क्या यह POSIX-compliant गोले में सिर्फ एक आम सम्मेलन है? मुझे इस व्यवहार का उल्लेख करने वाले POSIX शेल कमांड लैंग्वेज पेज पर कुछ भी नहीं मिला।


4
बेहतर सवाल यह है "क्या एक विशेष अर्थ $ प्राप्त होता है अगर यह एक शब्द में अंतिम चरित्र है?" कोई एक विशेष अर्थ नहीं दिया गया है $; इसका उपयोग कई, लेकिन अलग-अलग, विस्तार, पैरामीटर विस्तार ${...}, कमांड प्रतिस्थापन $(...)और अंकगणितीय अभिव्यक्तियों को पेश करने के लिए किया जाता है $((...))। कुछ गोले अतिरिक्त संदर्भों को पेश करते हैं, जैसे कि kshकमांड-प्रतिस्थापन संस्करण x=${ echo foo; echo bar;}(जो मानक से भिन्न होता है $(...), कमांड को सब्स्क्रिप्शन में निष्पादित नहीं करता है)।
शेपनर

@chepner क्या आप इस्साक और माइकल होमर के बीच मतभेद के आधार पर वजन करना चाहेंगे? उनके जवाब स्पष्ट रूप से एक दूसरे के विरोधाभासी हैं
हेरोल्ड फिशर

1
मैं माइकल होमर की व्याख्या से सहमत हूं; शेल पूर्ण होने के बाद तक विस्तार के बारे में चिंता करना शुरू नहीं करता है, इसलिए एकल शब्द में ab$, कोई वर्ण निम्नलिखित नहीं है $, चाहे वह मूल इनपुट स्ट्रिंग में एक अशक्त चरित्र द्वारा "पीछा" किया गया हो या एक मामले में एक स्थान हो। जैसे echo ab$ foo; मूल निर्विवाद व्हाट्सएप को पार्स करने के बाद मान्यता दी गई है और खारिज कर दिया गया है।
चेपनर

जवाबों:


10

$अपने आप से एक विशेष अर्थ नहीं है (कोशिश echo $), केवल जब इसके बाद अन्य चरित्र के साथ संयुक्त और एक विस्तार, उदाहरण $var(या ${var}), $(util)और $((1+2))

$अपने "विशेष" हो जाता है धारा के तहत POSIX मानक में एक विस्तार को परिभाषित करने के रूप में अर्थ टोकन मान्यता :

यदि वर्तमान चरित्र एक गैर उद्धृत है $या `:, खोल पैरामीटर विस्तार, आदेश प्रतिस्थापन, या उनके परिचयात्मक गैर उद्धृत चरित्र दृश्यों से गणित के विस्तार के लिए किसी भी उम्मीदवारों की शुरुआत की पहचान करेगा $या ${, $(या `, और $((क्रमश:। शेल को यूनिट के अंत का विस्तार करने के लिए पर्याप्त इनपुट पढ़ा जाएगा ( जैसा कि उद्धृत अनुभागों में बताया गया है)। वर्णों को संसाधित करते समय, यदि प्रतिस्थापन के उद्धरण या उद्धरण प्रतिस्थापन के भीतर निहित पाए जाते हैं, तो शेल पुन: निर्माण के लिए निर्दिष्ट तरीके से उन्हें संसाधित करेगा जो पाया जाता है। प्रतिस्थापन की शुरुआत से लेकर अंत तक पाए जाने वाले वर्ण, किसी भी पुनरावृत्ति के लिए अनुमति देता है, जो अंतर्निहित निर्माणों को पहचानने के लिए आवश्यक है, परिणाम टोकन में किसी भी एम्बेडेड या संलग्न प्रतिस्थापन ऑपरेटर या उद्धरण सहित अनमोल शामिल किए जाएंगे। प्रतिस्थापन के अंत तक टोकन को सीमांकित नहीं किया जाएगा।

इसलिए, यदि $विस्तार नहीं होता है , तो अन्य नियम लागू हो जाते हैं:

यदि पिछला वर्ण किसी शब्द का हिस्सा था, तो वर्तमान वर्ण को उस शब्द से जोड़ा जाएगा।

जो आपकी ab$स्ट्रिंग को कवर करता है।

एक अकेला के मामले में $("नया शब्द" $अपने आप होगा):

वर्तमान वर्ण का उपयोग नए शब्द की शुरुआत के रूप में किया जाता है।

अर्थ उत्पन्न शब्द एक युक्त $कि नहीं एक मानक विस्तार स्पष्ट रूप से POSIX द्वारा अनिर्दिष्ट के रूप में परिभाषित किया गया है है।

यह भी ध्यान दें कि $यह अंतिम वर्ण है $$, लेकिन यह भी उस चर का होता है जो वर्तमान शेल के PID को धारण करता है। में bash, !$एक इतिहास विस्तार (पिछली कमांड से आखिरी तर्क) को लागू कर सकता है। तो सामान्य तौर पर, नहीं, $बिना शब्द के अंत में अर्थ के बिना नहीं है, लेकिन एक शब्द के अंत में यह कम से कम एक मानक विस्तार को निरूपित नहीं करता है।


7

सटीक स्थिति के आधार पर, यह या तो स्पष्ट रूप से अनिर्दिष्ट है (इसलिए क्रियान्वयन वे कर सकते हैं) या आपके द्वारा देखे जाने के लिए आवश्यक हैं। आपके सटीक परिदृश्य में echo ab$, POSIX आउटपुट "ab $" को अनिवार्य करता है जिसे आपने देखा था और यह अनिर्दिष्ट नहीं है । सभी अलग-अलग मामलों का एक त्वरित सारांश अंत में है।

दो तत्व हैं: पहले शब्दों में टोकन, और फिर उन शब्दों की व्याख्या।


Tokenisation

पॉसिक्स टोकन की आवश्यकता है कि एक $वैध पैरामीटर विस्तार , कमांड प्रतिस्थापन , या अंकगणितीय प्रतिस्थापन की शुरुआत नहीं है जिसे WORDटोकन का शाब्दिक हिस्सा माना जाता है । ऐसा इसलिए है क्योंकि नियम 5 ("यदि वर्तमान चरित्र एक निर्विवाद है $या `, शेल पैरामीटर विस्तार, कमांड प्रतिस्थापन, या अंकगणित के विस्तार के लिए किसी भी उम्मीदवार की शुरुआत की पहचान करेगा उनके परिचयात्मक निर्विवाद चरित्र अनुक्रमों से: $या ${, $(और `, और $((, क्रमशः" ) लागू नहीं होता है, क्योंकि उनमें से कोई भी विस्तार वहां व्यवहार्य नहीं है। पैरामीटर विस्तार के लिए एक मान्य नाम की आवश्यकता होती है, और वहां एक खाली नाम मान्य नहीं होता है।

जब से यह नियम लागू नहीं हुआ, तब तक हम अनुसरण करते रहते हैं जब तक कि हम ऐसा नहीं करते। दो उम्मीदवार # 8 हैं ("यदि पिछला वर्ण किसी शब्द का हिस्सा था, तो वर्तमान वर्ण उस शब्द में जोड़ा जाएगा।") और # 10 ("वर्तमान वर्ण का उपयोग नए शब्द की शुरुआत के रूप में किया जाता है।") , जो क्रमशः echo a$और echo $क्रमशः लागू होते हैं।

फॉर्म का एक तीसरा मामला भी है echo a$+bजो एक ही दरार से गिरता है, क्योंकि +एक विशेष पैरामीटर का नाम नहीं है। यह हम बाद में लौटेंगे, क्योंकि यह नियमों के विभिन्न भागों को ट्रिगर करता है।

इस प्रकार विनिर्देशन की आवश्यकता है कि $शब्द को वाक्य रचना का एक हिस्सा माना जाए, और इसे बाद में आगे संसाधित किया जा सकता है।


शब्द विस्तार

इनपुट को इस तरह से पार्स करने के बाद $, शब्द में शामिल करने के साथ , शब्द विस्तार को उन प्रत्येक शब्दों पर लागू किया जाता है जिन्हें पढ़ा गया है। प्रत्येक शब्द को व्यक्तिगत रूप से संसाधित किया जाता है

यह निर्दिष्ट है कि :

यदि एक निर्विवाद '$' का अनुसरण एक वर्ण द्वारा किया जाता है, जो निम्न में से एक नहीं है:

  • एक संख्यात्मक चरित्र
  • विशेष मापदंडों में से एक का नाम ( विशेष पैरामीटर देखें )
  • एक चर नाम का एक मान्य पहला वर्ण
  • A <left-curly-bracket>('{')
  • <left-parenthesis>

परिणाम अनिर्दिष्ट है।

"अनिर्दिष्ट" यहाँ एक विशेष शब्द है जिसका अर्थ है

  1. एक अनुरूप खोल इस मामले में किसी भी व्यवहार का चयन कर सकता है
  2. एक अनुरूपण आवेदन किसी विशेष व्यवहार पर भरोसा नहीं कर सकता है

अपने उदाहरण में, echo ab$, $ द्वारा पीछा नहीं कर रहा है किसी भी चरित्र इसलिए यह नियम लागू नहीं होता है और अनिर्दिष्ट परिणाम लागू नहीं है। इसके द्वारा कोई विस्तार नहीं किया गया है $, इसलिए यह वस्तुतः मौजूद है और इसका प्रिंट आउट निकाल लिया गया है।

यह ऊपर से हमारे तीसरे मामले में कहां लागू होगाecho a$+b :। यहाँ $द्वारा पीछा किया जाता +है, जो एक नंबर, विशेष पैरामीटर नहीं है ( @, *, #, ?, -, $, !, या 0), एक चर के शुरू नाम (अंडरस्कोर या से एक अक्षरात्मक पोर्टेबल वर्ण सेट ), या कोष्ठक में से एक। इस मामले में, व्यवहार अनिर्दिष्ट है: एक अनुरूप शेल को विस्तार करने के लिए बुलाया एक विशेष पैरामीटर का आविष्कार करने की अनुमति है+ , और एक अनुरूपण अनुप्रयोग को यह नहीं मानना ​​चाहिए कि शेल नहीं करता है । शेल कुछ भी ऐसा कर सकता है जिसे वह पसंद करता है, जिसमें त्रुटि की रिपोर्ट करना भी शामिल है।

उदाहरण के लिए, zsh, अपने POSIX मोड में शामिल है, "वैरिएबल सेट" के रूप में व्याख्या $+bकरता हैb और इसके स्थान पर 1 या 0 को प्रतिस्थापित करता है। यह इसी तरह के लिए ~और एक्सटेंशन है =। यह अनुरूप व्यवहार है।

एक और जगह यह हो सकता है echo "a$ b"। फिर से, शेल को अपनी इच्छानुसार करने की अनुमति है, और $यदि आप शाब्दिक आउटपुट चाहते हैं तो स्क्रिप्ट लेखक को बचना चाहिए । यदि आप नहीं करते हैं, तो यह काम कर सकता है, लेकिन आप इस पर भरोसा नहीं कर सकते। यह विनिर्देशन का पूर्ण अक्षर है, लेकिन मुझे नहीं लगता कि इस प्रकार की ग्रेन्युलैरिटी का इरादा या विचार किया गया था।


संक्षेप में

  • echo ab$: शाब्दिक आउटपुट, पूरी तरह से निर्दिष्ट
  • echo a$ b: शाब्दिक आउटपुट, पूरी तरह से निर्दिष्ट
  • echo a$ b$: शाब्दिक आउटपुट, पूरी तरह से निर्दिष्ट
  • echo a$b: bपूरी तरह से निर्दिष्ट पैरामीटर का विस्तार
  • echo a$-b: विशेष पैरामीटर का विस्तार -, पूरी तरह से निर्दिष्ट
  • echo a$+b: अनिर्दिष्ट व्यवहार
  • echo "a$ b": अनिर्दिष्ट व्यवहार

एक के लिए $एक शब्द के अंत में, आप व्यवहार पर भरोसा करने की अनुमति दी जाती है और यह सचमुच इलाज और को पारित किया जाना चाहिए echoअपने तर्क के भाग के रूप आदेश। यह शेल पर एक अनुरूप आवश्यकता है।


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
terdon

@MichaelHomer echo $भी शाब्दिक और पूरी तरह से निर्दिष्ट होगा?
हेरोल्ड फिशर

@ हेरोल्डफिशर हां
माइकल होमर

कहाँ echo "$"और क्या echo "a b$"गिरना है?
हेरोल्ड फिशर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.