चूंकि फ़ाइल सिस्टम द्वारा मान्यता प्राप्त निष्पादन योग्य में से किसी भी प्रकार की नहीं है, और यह मानकर कि आपको उस फ़ाइल को निष्पादित करने की अनुमति मिल गई है, execve()सिस्टम कॉल आमतौर पर ENOEXEC( निष्पादन योग्य नहीं ) त्रुटि के साथ विफल हो जाएगी ।
तब क्या होता है, एप्लिकेशन और / या लाइब्रेरी फंक्शन कमांड को निष्पादित करने के लिए उपयोग किया जाता है।
यह उदाहरण के लिए एक शेल, execlp()/ execvp()libc फ़ंक्शन हो सकता है।
जब वे कमांड चलाते हैं, तो अधिकांश अन्य एप्लिकेशन उन दोनों में से किसी एक का उपयोग करेंगे। वे उदाहरण के लिए system("command line")libc फ़ंक्शन के माध्यम से शेल खोलेंगे, जो आम तौर पर shउस कमांड लाइन को पार्स करने के लिए आमंत्रित करेगा (जिसका पथ संकलन समय पर निर्धारित किया जा सकता है (जैसे /bin/shबनाम)/usr/xpg4/bin/sh सोलारिस पर)), या $SHELLस्वयं द्वारा संग्रहीत शेल को आमंत्रित करें viइसकी !कमांड, या xterm -e 'command line'कई अन्य कमांड के साथ ( su user -cउपयोगकर्ता के लॉगिन शेल को बदले में देगा $SHELL)।
आम तौर पर, एक शेबंग-लेस टेक्स्ट फ़ाइल जो शुरू नहीं होती #है, उसे shस्क्रिप्ट के रूप में माना जाता है । कौन सा shयह हालांकि अलग-अलग होगा है।
execlp()/ execvp(), execve()लौटने पर ENOEXECआम तौर shपर उस पर आह्वान किया जाएगा। उन प्रणालियों के लिए जिनके पास एक से अधिक हैं, shक्योंकि वे एक से अधिक मानक के अनुरूप हो सकते हैं, जो shकि आम तौर पर संकलन समय पर निर्धारित किया जाएगा ( कोड का उपयोग करके execvp()/ execlp()कोड के एक अलग ब्लॉब को लिंक करके जो एक अलग पथ को संदर्भित करता है sh)। उदाहरण के लिए, सोलारिस पर, वह या तो /usr/xpg4/bin/sh(एक मानक, POSIX sh) या /bin/sh(बॉर्न शेल (एक प्राचीन शैल) सोलारिस 10 पर और पुराने, ksh93 सोलारिस 11 में) होगा।
जब गोले की बात आती है, तो बहुत भिन्नता होती है। bash, एटी एंड टी ksh, बॉर्न शेल आम तौर पर स्क्रिप्ट की व्याख्या खुद करेगा (एक बच्चे की प्रक्रिया में जब तक execउपयोग नहीं किया जाता है) एक सिम्युलेटेड होने के बाद execve(), वह सभी unexported चर को बंद कर देता है, सभी बंद-पर-एफडीएस बंद कर देता है, सभी कस्टम जाल हटा दिए गए हैं, उपनाम, कार्य ... ( bashमें स्क्रिप्ट की व्याख्या करेंगेsh मोड )। yashखुद को निष्पादित करेंगे (के साथ shके रूप में argv[0]तो में shयह व्याख्या करने के लिए मोड)।
zsh, pdksh , ashआधारित गोले आम तौर पर लागू करेगाsh (पथ संकलन समय में जिनमें से निर्धारित)।
के लिए cshऔर tcsh(और shकुछ शुरुआती BSDs के), फ़ाइल का पहला वर्ण है अगर# , तो वे खुद को यह व्याख्या करने के लिए, और निष्पादित करेंगे shअन्यथा। यह एक पूर्व-शेबांग समय पर वापस जाता है जहां टिप्पणियों के रूप में cshपहचाना #जाता है, लेकिन बॉर्न शेल नहीं, इसलिए #यह संकेत था कि यह एक csh स्क्रिप्ट थी।
fish (कम से कम संस्करण 2.4.0), बस एक त्रुटि देता है अगर execve() विफल रहता है (यह एक स्क्रिप्ट के रूप में इलाज करने का प्रयास नहीं करता है)।
कुछ गोले (जैसे) bash या एटी एंड टीksh ) पहले हेयुरिस्टिकली यह निर्धारित करने की कोशिश करेंगे कि फाइल का मतलब स्क्रिप्ट है या नहीं। तो आप पा सकते हैं कि कुछ गोले एक स्क्रिप्ट को निष्पादित करने से इंकार कर देंगे अगर यह पहले कुछ बाइट्स में एक एनयूएल चरित्र मिला है।
यह भी ध्यान दें कि यदि execve() ENOEXEC के साथ विफल रहता है, लेकिन फ़ाइल में एक शेलबैंग लाइन है, तो कुछ गोले उस शेलबैंग लाइन की व्याख्या करने की कोशिश करते हैं।
तो कुछ उदाहरण:
- जब
$SHELLहै /bin/bash, विधा में व्याख्या की xterm -e 'myscript with args'जाएगी । के साथ , का उपयोग करेंगे , तो स्क्रिप्ट द्वारा व्याख्या की जाएगीmyscriptbashshxterm -e myscript with argsxtermexecvp()sh ।
su -c myscriptसोलारिस 10 पर जहां rootलॉगिन शेल है /bin/shऔर /bin/shबोर्न शेल हैmyscript व्याख्या ।
/usr/xpg4/bin/awk 'BEGIN{system("myscript")' सोलारिस 10 पर इसकी व्याख्या की जाएगी /usr/xpg4/bin/sh (उसी के लिए /usr/xpg4/bin/env myscript) की जाएगी।
find . -prune -exec myscript {} \;सोलारिस 10 पर (उपयोग करके execvp()) इसकी व्याख्या की जाएगी/bin/sh भी साथ /usr/xpg4/bin/find, यहां तक कि एक POSIX पर्यावरण (एक अनुरूपता बग) में।
csh -c myscriptcshअगर यह इसके साथ शुरू होता है #, तो shअन्यथा इसकी व्याख्या करेगा ।
सब सब में, आप यह सुनिश्चित नहीं कर सकते हैं कि उस स्क्रिप्ट की व्याख्या करने के लिए किस शेल का उपयोग किया जाएगा यदि आप नहीं जानते कि यह कैसे और क्या इसे लागू किया जाएगा।
किसी भी स्थिति में, read -pएक-एक bashवाक्य रचना है, इसलिए आप यह सुनिश्चित करना चाहेंगे कि स्क्रिप्ट की व्याख्या की जाए bash(और उस भ्रामक .shविस्तार से बचें )। या तो आप bashनिष्पादन योग्य और उपयोग का मार्ग जानते हैं:
#! /path/to/bash -
read -p ...
या आप का उपयोग करके निष्पादन योग्य (मान स्थापित किया गया है) $PATHकी एक खोज पर भरोसा कर सकते हैं :bashbash
#! /usr/bin/env bash
read -p ...
( envलगभग सर्वव्यापी रूप से पाया जाता है /usr/bin)। वैकल्पिक रूप से, आप इसे POSIX + Bourne संगत बना सकते हैं जिस स्थिति में आप उपयोग कर सकते हैं /bin/sh। सभी प्रणालियों में एक होगा /bin/sh। उनमें से अधिकांश पर यह (अधिकांश भाग के लिए) POSIX- संगत होगा, लेकिन आप इसके बजाय अभी और फिर एक बॉर्न शेल खोज सकते हैं।
#! /bin/sh -
printf >&2 'Enter a user name: '
read user
printf '%s\n' "$user"