POSIX द्वारा `#! 'वाक्यविन्यास का व्यवहार अनिर्दिष्ट क्यों है?


17

POSIX विनिर्देशन के शेल कमांड भाषा पृष्ठ से:

यदि शेल कमांड्स की फाइल की पहली पंक्ति "#!" अक्षर से शुरू होती है, तो परिणाम अनिर्दिष्ट होते हैं।

#!POSIX द्वारा अनिर्दिष्ट व्यवहार क्यों किया जाता है ? मुझे यह चकित करता है कि इतना पोर्टेबल और व्यापक रूप से इस्तेमाल किया गया कुछ अनिर्दिष्ट व्यवहार होगा।


1
मानकों को लागू करने के लिए अनिर्दिष्ट चीजों को छोड़ दें ताकि विशेष व्यवहारों को लागू न किया जा सके। उदाहरण के लिए, एक "लॉगिन" "अनिर्दिष्ट गतिविधि है जिसके द्वारा उपयोगकर्ता सिस्टम तक पहुँच प्राप्त करता है।"
Kusalananda

2
चूंकि POSIX निष्पादन योग्य पथों को निर्दिष्ट नहीं करता है, वैसे भी एक Shebang रेखा गैर-पोर्टेबल है; मुझे यकीन नहीं है कि इसकी परवाह किए बिना इसे प्राप्त करने से बहुत कुछ प्राप्त होगा।
माइकल होमर

1
@MichaelHomer, निश्चित रूप से नहीं? मानक निर्दिष्ट कर सकता है कि रेखा में दुभाषिया के लिए उपयोग करने के लिए एक पथ है, यहां तक ​​कि यह बताए बिना कि क्या पथ होना चाहिए।
ilkachachu १ '

1
@ हेरोल्डफिशर को छोड़कर शेल द्वारा व्याख्या नहीं की गई है, इसकी व्याख्या या तो ओएस कर्नेल द्वारा की गई है (कम से कम लिनक्स पर, जो वास्तव में बिल्ड समय के दौरान इस समर्थन को अक्षम कर सकता है), या जो भी लाइब्रेरी exec()फ़ंक्शन को लागू करता है। तो कई गोले के खिलाफ जाँच वास्तव में आपको बता नहीं है कि यह कितना पोर्टेबल है।
आस्टिन हेमलमेलगर

2
@HaroldFischer इसके अलावा, यहां तक ​​कि POSIX- अनुरूप ओएस के बीच भी व्यवहार सुसंगत नहीं है। लिनक्स और मैकओएस अलग तरह से व्यवहार करते हैं: लिनक्स रिक्त स्थान द्वारा पूरी तरह से शेबंग लाइन को टोकन नहीं करता है। macOS स्क्रिप्ट दुभाषिया को दूसरी स्क्रिप्ट नहीं होने देता। इसके अलावा en.wikipedia.org/wiki/Shebang_(Unix)#Portability
jamesdlin

जवाबों:


21

मुझे लगता है कि मुख्य रूप से क्योंकि:

  • व्यवहार कार्यान्वयन के बीच बहुत भिन्न होता है। देखें https://www.in-ulm.de/~mascheck/various/shebang/ सभी विवरण के लिए।

    हालाँकि यह अब अधिकांश यूनिक्स की तरह कार्यान्वयन का एक न्यूनतम सबसेट निर्दिष्ट कर सकता है: जैसे #! *[^ ]+( +[^ ]+)?\n(केवल एक या दो शब्दों में सेट किए गए पोर्टेबल फ़ाइल नाम वर्ण से) जहां पहला शब्द एक मूल निष्पादन योग्य मार्ग है, बात यह नहीं है बहुत लंबा और व्यवहार अनिर्दिष्ट है यदि निष्पादन योग्य सेट्युड / सेटगिड है, और कार्यान्वयन परिभाषित करता है कि दुभाषिया पथ या स्क्रिप्ट पथ argv[0]दुभाषिया के रूप में पारित किया गया है या नहीं ।

  • POSIX वैसे भी निष्पादनयोग्य का पथ निर्दिष्ट नहीं करता है। कई प्रणालियों में प्री-पोसिक्स उपयोगिताओं /bin/ में हैं /usr/binऔर पोसिक्स उपयोगिताओं को कहीं और है (जैसे सोलारिस 10 पर जहां /bin/shएक बॉर्न शेल है और एक /usr/xpg4/binपीओएसआईएक्स में है ; सोलारिस 11 ने इसे ksh93 के साथ बदल दिया है जो अधिक पीएक्सआईएक्स अनुपालन है, लेकिन अधिकांश अन्य उपकरण /binअभी भी प्राचीन गैर-पॉसिक्स वाले हैं)। कुछ सिस्टम POSIX वाले नहीं हैं, लेकिन POSIX मोड / एमुलेशन हैं। सभी POSIX की आवश्यकता है कि एक दस्तावेज वातावरण हो जिसमें एक प्रणाली POSIXly व्यवहार करती है।

    उदाहरण के लिए Windows + Cygwin देखें। दरअसल, विंडोज + साइग्विन के साथ, जब एक स्क्रिप्ट को एक साइबर एप्लीकेशन द्वारा नहीं बल्कि एक देशी विंडोज एप्लिकेशन द्वारा इनवॉइस किया जाता है, तो वह धमाकेदार होती है।

    तो भले ही POSIX ने Shebang तंत्र को निर्दिष्ट किया हो, इसका उपयोग POSIX sh/ sed/ awk... स्क्रिप्ट लिखने के लिए नहीं किया जा सकता है (यह भी ध्यान दें कि शेलबैंग तंत्र का उपयोग विश्वसनीय sed/ awkस्क्रिप्ट लिखने के लिए नहीं किया जा सकता है क्योंकि यह एक अंतिम विकल्प को पारित करने की अनुमति नहीं देता है मार्कर)।

अब तथ्य यह है कि यह अनिर्दिष्ट है इसका मतलब यह नहीं है कि आप इसका इस्तेमाल नहीं कर सकते हैं (ठीक है, यह कहता है कि आपके पास पहली पंक्ति शुरू नहीं होनी चाहिए #!यदि आप उम्मीद करते हैं कि यह केवल एक नियमित टिप्पणी होगी और वह एक धमाकेदार नहीं होगी), लेकिन यदि आप करते हैं तो POSIX आपको कोई गारंटी नहीं देता है।

मेरे अनुभव में, शेबबैंग का उपयोग करने से आपको शेल स्क्रिप्ट लिखने के पोसिक्स के तरीके का उपयोग करने की तुलना में पोर्टेबिलिटी की अधिक गारंटी मिलती है: शी-बैंग को छोड़ दें, पॉसिक्स shसिंटैक्स में स्क्रिप्ट लिखें और आशा करें कि जो भी स्क्रिप्ट स्क्रिप्ट को आमंत्रित करती है shवह उस पर एक पॉज़ल अनुपालन करता है, जो कि है ठीक है यदि आप जानते हैं कि स्क्रिप्ट सही उपकरण द्वारा सही वातावरण में लागू की जाएगी, लेकिन अन्यथा नहीं।

आपको ऐसे काम करने पड़ सकते हैं जैसे:

#! /bin/sh -
if : ^ false; then : fine, POSIX system by default
else
  # cover Solaris 10 or older. ": ^ false" returns false
  # in the Bourne shell as ^ is an alias for | there for
  # compatibility with the Thomson shell.
  PATH=`getconf PATH`:$PATH; export PATH
  exec /usr/xpg4/bin/sh - "$0" ${1+"$@"}
fi
# rest of script

आप Windows + Cygwin के लिए पोर्टेबल होने के लिए चाहते हैं, तो आप एक साथ अपनी फ़ाइल के नाम करना पड़ सकता है .batया .ps1विस्तार और के लिए कुछ इसी तरह की चाल का उपयोग cmd.exeया powershell.execygwin आह्वान करने के लिए shएक ही फाइल पर।


दिलचस्प बात यह है कि अंक 5 से : "निर्माण #! उस विस्तार को प्रदान करने के इच्छुक कार्यान्वयन के लिए आरक्षित है। एक पोर्टेबल एप्लिकेशन # का उपयोग नहीं कर सकता है! शेल स्क्रिप्ट की पहली पंक्ति के रूप में; यह एक टिप्पणी के रूप में व्याख्या नहीं की जा सकती है।"
मूरू

@muru यदि स्क्रिप्ट सही मायने में पोर्टेबल थी, तो POSIX चलाने वाली POSIX प्रणाली पर sh, इसे POSIX द्वारा निष्पादित किए जाने के साथ-साथ हैशबैंग लाइन की आवश्यकता नहीं होगी sh
Kusalananda

1
@ कुसलानंद केवल अगर सही execlpया execvpइस्तेमाल किया गया, सही है? अगर मैं उपयोग execveकर रहा होता तो इसका परिणाम ENOEXEC में होता?
मुरु

9

[T] वह व्यवहार सभी POSIX- शिकायत गोले के बीच सुसंगत लगता है। मैं यहाँ wiggle कमरे की आवश्यकता को नहीं देखता।

आप काफी गहराई से नहीं देख रहे हैं।

1980 के दशक में, यह तंत्र वास्तविक रूप से मानकीकृत नहीं था । यद्यपि डेनिस रिची ने इसे लागू किया था, लेकिन यह कार्यान्वयन ब्रह्मांड के एटी एंड टी पक्ष में जनता तक नहीं पहुंचा था। यह प्रभावी रूप से केवल सार्वजनिक रूप से उपलब्ध और बीएसडी में जाना जाता था; निष्पादन योग्य शेल स्क्रिप्ट एटी एंड टी यूनिक्स पर उपलब्ध नहीं है। इस प्रकार इसे मानकीकृत करना उचित नहीं था। इस समकालीन डोको द्वारा मामलों की स्थिति का उदाहरण दिया जाता है:

ध्यान दें कि बीएसडी उन फाइलों को अनुमति देता है जो #! interpreterसीधे निष्पादित होने लगती हैं, जबकि SysV केवल a.out फ़ाइलों को सीधे निष्पादित करने की अनुमति देता है। इसका मतलब यह है कि exec…()बीएसडी कार्यक्रम में दिनचर्या में से एक का उदाहरण SysV के तहत बदले जा सकता है ताकि /bin/shउस कार्यक्रम के लिए दुभाषिया (typlically ) को निष्पादित किया जा सके ।
- स्टीफन फ्रेड (1988)। "सिस्टम एक्स रिलीज़ वाई पर प्रोग्रामिंग"। ऑस्ट्रेलियाई यूनिक्स सिस्टम उपयोगकर्ता समूह न्यूज़लैटर । मात्रा 9. संख्या 4. पी। 111।

यहां एक महत्वपूर्ण बिंदु यह है कि आप गोले को देख रहे हैं, जबकि निष्पादन योग्य शेल स्क्रिप्ट का अस्तित्व वास्तव में exec…()कार्यों के लिए एक मामला है । क्या गोले निष्पादन योग्य स्क्रिप्ट तंत्र के अग्रदूतों में शामिल हैं , अभी भी आज भी कुछ गोले में पाए जाते हैं (और आजकल exec…p()के कार्यों के सबसेट के लिए भी अनिवार्य है ), और कुछ भ्रामक है। इस संबंध में मानक की क्या आवश्यकता है exec…(), व्याख्यात्मक स्क्रिप्ट कैसे काम करती है, और उस समय POSIX को मूल रूप से बनाया गया था, यह लक्ष्य ऑपरेटिंग सिस्टम के स्पेक्ट्रम के एक प्रमुख हिस्से में पहले स्थान पर काम नहीं करता था

एक अधीनस्थ प्रश्न क्यों इस के बाद से मानकीकृत नहीं किया गया है, विशेष रूप से के रूप में स्क्रिप्ट दुभाषियों के लिए जादुई संख्या तंत्र है था ब्रह्मांड के एटी एंड टी पक्ष में जनता पर पहुंच गया और के लिए दर्ज किया गया था exec…()में सिस्टम 5 इंटरफ़ेस परिभाषा , 1990 के दशक के अंत से :

एक दुभाषिया फ़ाइल फॉर्म की एक पंक्ति के साथ शुरू होती है

#! pathname [arg]
जहाँ pathname दुभाषिया का पथ है, और arg एक वैकल्पिक तर्क है। जब आप execएक दुभाषिया फ़ाइल करते हैं, तो सिस्टम execनिर्दिष्ट दुभाषिया होता है।
- execसिस्टम वी इंटरफ़ेस परिभाषा । वॉल्यूम 1. 1991।

दुर्भाग्य से, यह व्यवहार आज भी लगभग उतना ही व्यापक है जितना कि 1980 के दशक में था और इसका मानकीकरण करने का कोई सामान्य व्यवहार नहीं है। कुछ यूनीक (प्रसिद्ध एचपी-यूएक्स और फ्रीबीएसडी, उदाहरण के लिए) स्क्रिप्ट के लिए दुभाषियों के रूप में स्क्रिप्ट का समर्थन नहीं करते हैं। चाहे पहली पंक्ति एक, दो, या व्हाट्सएप द्वारा अलग किए गए कई तत्व मैकओएस (और 2005 से पहले फ्रीबीएसडी के संस्करण) और अन्य के बीच भिन्न हो। अधिकतम समर्थित पथ की लंबाई भिन्न होती है। और POSIX पोर्टेबल फ़ाइल नाम वर्ण सेट के साथ के रूप में, अक्षर प्रमुख हैं और व्हाट्सएप को पीछे छोड़ रहे हैं। क्या पूरे सिस्टम में महत्वपूर्ण भिन्नता के साथ, 0, 1 और 2 का तर्क समाप्त हो रहा है। कुछ वर्तमान में POSIX-अनुरूप लेकिन गैर-यूनिक्स सिस्टम अभी भी इस तरह के किसी भी तंत्र का समर्थन नहीं करते हैं, और यह अनिवार्य है कि उन्हें अब POSIX अनुरूप नहीं बनाया जाएगा।

आगे की पढाई


1

जैसा कि कुछ अन्य जवाबों के अनुसार, कार्यान्वयन अलग-अलग हैं। इससे मौजूदा स्क्रिप्ट के साथ पिछड़ी-अनुकूलता को मानकीकृत और संरक्षित करना कठिन हो जाता है । यह आधुनिक POSIX सिस्टम के लिए भी सही है। उदाहरण के लिए, लिनक्स रिक्त स्थान द्वारा शेलबैंग लाइन को पूरी तरह से टोकन नहीं करता है। macOS स्क्रिप्ट दुभाषिया को दूसरी स्क्रिप्ट नहीं होने देता।

Http://en.wikipedia.org/wiki/Shebang_(Unix)#Portability भी देखें

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