2012-09-06 6 views
20

मैं एक साधारण खोल स्क्रिप्ट लेखन और पाया बाहर है कि मेरे खोल स्क्रिप्ट कुटिया लाइन अगर मैं अपने स्क्रिप्ट के लिए अनुमति निष्पादित और ./myscript.sh का उपयोग कर निष्पादित देने की आवश्यकता नहीं हैशैल स्क्रिप्ट शेबांग लाइन के बिना ठीक काम कर रही है? क्यूं कर?

#!/bin/sh 

किया गया था। यह ठीक चलाता है।

मैं bash खोल का उपयोग कर रहा हूं और /bin/sh वास्तव में bash पर इंगित कर रहा है।

lrwxrwxrwx 1 root root /bin/sh -> bash 

मुझे पता है कि मामला लाइन जो दुभाषिया स्क्रिप्ट के अपने आराम के लिए उपयोग करने के लिए खोल बताने के लिए प्रयोग किया जाता है।

यदि मुझे पर्ल में शेबांग लाइन याद आती है, तो निष्पादन अनुमति दें और ./myscript.pl चलाएं, यह काम नहीं करता है।

वास्तव में यहां क्या हो रहा है? अगर मैं ./ का उपयोग करता हूं, तो शेबांग लाइन को वास्तव में कब चाहिए?

उत्तर

14

कुटिया लाइन यह रूप में sh file.sh मंगलाचरण का विरोध करने के लिए निष्पादन योग्य के रूप में चलाने के लिए बने है फ़ाइल और केवल तभी (में की जरूरत है। यह वास्तव में स्क्रिप्ट के द्वारा की जरूरत नहीं है, यह प्रणाली कैसे दुभाषिया खोजने के लिए पता करने के लिए के लिए है।

संपादित:। सवाल ग़लत व्याख्या के लिए क्षमा करें कुटिया लाइन याद आ रही है या मान्यता प्राप्त नहीं हैं, तो /bin/sh प्रयोग किया जाता है लेकिन मैं दुभाषिया के बारे में स्पष्ट किया जा रहा पसंद करते हैं

ध्यान दें, कि इस व्यवहार सार्वभौमिक नहीं है,।। आईआईआरसी, केवल कुछ exec* पारिवारिक कार्य ऐसा करते हैं (टी नहीं o विभिन्न प्लेटफार्मों का जिक्र करें), इसलिए यहां स्पष्ट होने का एक और कारण है।

+2

ओपी का कहना है कि वह स्क्रिप्ट को '।/Myscript.sh'' के रूप में आमंत्रित करता है - मुझे लगता है कि इसका मतलब है कि वह स्पष्ट रूप से निष्पादन योग्य और स्क्रिप्ट के रूप में शैल का उपयोग तर्क के रूप में नहीं कर रहा है। –

+0

हां। लेकिन लिपि उस लाइन के बिना चल रही है? क्यूं कर? मैं स्क्रिप्ट चलाने के लिए '।/Myscript.sh' का उपयोग कर रहा हूं। –

+0

ओह। जवाब संपादित, धन्यवाद। –

13

पैरेंट खोल, जहां आपने ./myscript.sh दर्ज किया था, पहले execve पर प्रयास किया, जहां मौजूद है तो शेबैंग लाइन प्रभावी होगी। जब यह काम करता है, तो माता-पिता स्क्रिप्ट और ईएलएफ के बीच के अंतर से अनजान हैं क्योंकि कर्नेल इसका ख्याल रखता है।

execve विफल रहा, इसलिए एक प्राचीन यूनिक्स संगतता सुविधा, शेबांग लाइनों के अस्तित्व की भविष्यवाणी करने के लिए सक्रिय थी। यह अनुमान लगाया गया है कि एक फ़ाइल जो निष्पादित अनुमति है लेकिन कर्नेल द्वारा वैध निष्पादन योग्य फ़ाइल के रूप में पहचाना नहीं गया है, एक शेल स्क्रिप्ट होना चाहिए।

आमतौर पर अभिभावक खोल का अनुमान है कि स्क्रिप्ट एक ही खोल के लिए लिखा गया है (न्यूनतम बोर्न-जैसे गोले /bin/sh के साथ स्क्रिप्ट चलाते हैं, बैश इसे बैश सबप्रोसेस के रूप में चलाता है), सीएसएच पहले कुछ के आधार पर कुछ और जटिल अनुमान लगाता है चरित्र क्योंकि यह शेबांग भी भविष्यवाणी करता है और इसे बोर्न शैल के साथ मिलकर रहने की आवश्यकता होती है)।

जब आपको पता है कि ये अनुमान गलत होंगे (उदाहरण के लिए शेबैंग #!/usr/bin/perl है), या जब आप लगातार काम करने के अनुमान लगाने पर भरोसा नहीं करते हैं, या जब स्क्रिप्ट द्वारा चलाने योग्य होने की आवश्यकता होती है, तो आपको एक शेबांग लाइन की आवश्यकता होती है अभिभावक प्रक्रिया जो एक खोल नहीं है।

+1

अधिक जानकारी के उत्तर में पाया जा सकता है * कुछ स्क्रिप्ट क्यों # से शुरू होती हैं! ...? * http://www.faqs.org/faqs/unix-faq/faq/part3/section-16.html –

3

POSIX (एकल यूनिक्स विशिष्टता 4) मानक नहीं उपयोगी है: "#"

खोल आदेशों की फ़ाइल की पहली पंक्ति पात्रों के साथ शुरू होता है , परिणाम निर्दिष्ट नहीं हैं।

तो, मानक का तात्पर्य है कि यदि आपके पास # नहीं है!तो इसे एक पॉज़िक्स खोल चलाना चाहिए। लेकिन आधुनिक गोले POSIX अनुरूप नहीं हैं। पुरानी कॉर्न शैल 88 (ksh88) ने बोर्न शेल (एक पॉज़िक्स खोल के करीब) भाग लिया, बिना #! लाइन, लेकिन ksh93 तोड़ता है, और बाश भी करता है। Ksh93 और Bash दोनों के साथ, यदि कोई # नहीं तो वे अपना स्वयं का खोल चलाते हैं! रेखा मौजूद है।

लोकप्रिय राय के बावजूद, बैश और कॉर्न गोले अलग-अलग हैं। जब आप एक शेल स्क्रिप्ट लिखते हैं तो आप कभी भी यह सुनिश्चित नहीं कर सकते कि आप किस शेल से भागेंगे, या यहां तक ​​कि यदि यह किसी अन्य शेल से भी चलाया जाएगा (अधिकांश प्रोग्रामिंग भाषाएं अन्य प्रोग्राम चला सकती हैं)। बोर्न/पॉज़िक्स सिंटैक्स के बाहर आप जिस चीज का उपयोग करते हैं, वह आपको स्कूपीड किया जाएगा।

हमेशा एक # का उपयोग करें! लाइन, इसे मौके पर मत छोड़ो।

+2

पर सवाल खोल अनुपालन के बारे में आपका बयान उलट दिया गया है। केश और बैश जैसे आधुनिक गोले POSIX अनुपालन (या कम से कम बहुत करीब हैं) जबकि बोर्न शैल निश्चित रूप से नहीं है। खोल के लिए प्रारंभिक POSIX मानक अनिवार्य रूप से ksh88 था। जब मानक मानक पॉज़िक्स अनुपालन खोल का उपयोग किया जाना चाहिए, तो यह बैश और क्षीश के लिए खुद को चलाने के लिए उचित बनाता है। बैश, ksh88 और ksh93 निश्चित रूप से भिन्न हैं, लेकिन वे क्षेत्र जहां वे करते हैं या तो मानक या उसके दायरे के बाहर अनिर्दिष्ट व्यवहार हैं। – jlliagre

+0

@jlliagre: POSIX का कहना है कि 'sh' चलाया जाता है यदि कोई '#!' नहीं है, ksh या bash नहीं। जब बैश एक गैर- # चलाता है! लाइन स्क्रिप्ट यह POSIX मोड (--posix) में या sh प्रतीकात्मक लिंक के रूप में नहीं चलती है। POSIX ksh88 पर आधारित हो सकता है, लेकिन मैंने विशेष रूप से ksh93 का उल्लेख किया है, जो POSIX मानक में sh से काफी अलग है (उदाहरण के लिए कार्यों में टाइप किए गए ksh88 और POSIX के बीच मतभेद हैं), हालांकि यह सच है कि, SFAIK, ksh93 पॉज़िक्स sh का एक सुपर-सेट है (यही कारण है कि कार्यों में टाइपपीफ ksh88 से 93 तक बदल गया)। मैं अपनी सलाह से खड़ा हूं कि हमेशा '#!' लाइन निर्दिष्ट करना बुद्धिमानी है। – cdarke

+1

आप गलत मानते हैं/bin/sh हमेशा POSIX है। POSIX यह नहीं कहता है कि कोई शेबैंग नहीं होने पर/bin/sh चलाया जाता है लेकिन जब आप पहले से ही POSIX वातावरण के अंतर्गत होते हैं, तो POSIX खोल किसी स्क्रिप्ट को बिना किसी शेबैंग की व्याख्या करेगा। यह इस खोल को एक विशेष पथनाम रखने के लिए जरूरी नहीं है। यह कार्यान्वयनकर्ता पर निर्भर करता है कि वह अपना नाम (संभवतः sh) और पथ को परिभाषित करे जो हो सकता है कि सोलारिस 10/usr/xpg4/bin की तरह/bin। यही कारण है कि मैं पोर्टेबल शैल स्क्रिप्ट्स को सलाह देता हूं कि मानक शेडबैक न हो। यदि आपका खोल POSIX मोड के रूप में चल रहा है और आप एक गैर # कॉल करते हैं! स्क्रिप्ट, यह भी POSIX मोड में चलाया जाएगा। – jlliagre

संबंधित मुद्दे