exec
लिनक्स कर्नेल का सिस्टम कॉल देशी #!
रूप से शेबांग ( ) को समझता है
जब आप बैश पर करते हैं:
./something
लिनक्स पर, यह exec
सिस्टम कॉल को पथ के साथ कॉल करता है ./something
।
कर्नेल की इस लाइन को पास की गई फ़ाइल पर कॉल किया जाता है exec
: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
यह फ़ाइल के पहले बाइट्स को पढ़ता है, और उनकी तुलना करता है #!
।
यदि तुलना सही है, तो बाकी लाइन को लिनक्स कर्नेल द्वारा पार्स किया जाता है, जो पहले तर्क के रूप में exec
पथ /usr/bin/env python
और वर्तमान फ़ाइल के साथ एक और कॉल करता है:
/usr/bin/env python /path/to/script.py
और यह किसी भी स्क्रिप्टिंग भाषा के लिए काम करता है #
जो एक टिप्पणी चरित्र के रूप में उपयोग करता है ।
और हाँ, आप एक अनंत लूप बना सकते हैं:
printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a
बैश त्रुटि को पहचानता है:
-bash: /a: /a: bad interpreter: Too many levels of symbolic links
#!
बस मानव पठनीय होना होता है, लेकिन इसकी आवश्यकता नहीं है।
यदि फ़ाइल अलग-अलग बाइट्स के साथ शुरू होती है, तो exec
सिस्टम कॉल एक अलग हैंडलर का उपयोग करेगा। अन्य सबसे महत्वपूर्ण अंतर्निहित हैंडलर ELF निष्पादन योग्य फ़ाइलों के लिए है: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305 जो बाइट्स की जांच करता है 7f 45 4c 46
(जो मानव भी होता है के लिए पठनीय .ELF
)। आइए पुष्टि करते हैं कि 4 पहले बाइट्स को पढ़कर /bin/ls
, जो एक ईएलएफ निष्पादन योग्य है:
head -c 4 "$(which ls)" | hd
उत्पादन:
00000000 7f 45 4c 46 |.ELF|
00000004
इसलिए जब कर्नेल उन बाइट्स को देखता है, तो वह ईएलएफ फ़ाइल लेता है, इसे सही ढंग से मेमोरी में डालता है, और इसके साथ एक नई प्रक्रिया शुरू करता है। इसे भी देखें: https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#3131386861
अंत में, आप binfmt_misc
तंत्र के साथ अपने खुद के शेबंग हैंडलर जोड़ सकते हैं । उदाहरण के लिए, आप फ़ाइलों के लिए.jar
एक कस्टम हैंडलर जोड़ सकते हैं । यह तंत्र फ़ाइल एक्सटेंशन द्वारा हैंडलर का भी समर्थन करता है। एक अन्य आवेदन QEMU के साथ एक अलग वास्तुकला के पारदर्शी रूप से चलाने के लिए है ।
मुझे नहीं लगता कि POSIX शेबन्स को निर्दिष्ट करता है, हालांकि: https://unix.stackexchange.com/a/346214/32558 , हालांकि यह इसका उल्लेख औचित्य वर्गों में करता है, और फॉर्म में "यदि निष्पादन योग्य स्क्रिप्ट सिस्टम द्वारा समर्थित हैं तो कुछ हो सकता है"।
chmod +x my_shell_script.sh ; /path/to/my_shell_script.sh # or ./my_shell_script.sh if you happen to be in its directory