चूंकि फ़ाइल सिस्टम द्वारा मान्यता प्राप्त निष्पादन योग्य में से किसी भी प्रकार की नहीं है, और यह मानकर कि आपको उस फ़ाइल को निष्पादित करने की अनुमति मिल गई है, 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'
जाएगी । के साथ , का उपयोग करेंगे , तो स्क्रिप्ट द्वारा व्याख्या की जाएगीmyscript
bash
sh
xterm -e myscript with args
xterm
execvp()
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 myscript
csh
अगर यह इसके साथ शुरू होता है #
, तो sh
अन्यथा इसकी व्याख्या करेगा ।
सब सब में, आप यह सुनिश्चित नहीं कर सकते हैं कि उस स्क्रिप्ट की व्याख्या करने के लिए किस शेल का उपयोग किया जाएगा यदि आप नहीं जानते कि यह कैसे और क्या इसे लागू किया जाएगा।
किसी भी स्थिति में, read -p
एक-एक bash
वाक्य रचना है, इसलिए आप यह सुनिश्चित करना चाहेंगे कि स्क्रिप्ट की व्याख्या की जाए bash
(और उस भ्रामक .sh
विस्तार से बचें )। या तो आप bash
निष्पादन योग्य और उपयोग का मार्ग जानते हैं:
#! /path/to/bash -
read -p ...
या आप का उपयोग करके निष्पादन योग्य (मान स्थापित किया गया है) $PATH
की एक खोज पर भरोसा कर सकते हैं :bash
bash
#! /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"