क्यों सभी स्क्रिप्ट फ़ाइलों के साथ शुरू करते हैं
#!/bin/sh
या के साथ
#!/bin/csh
क्या यह आवश्यक है? इसका उद्देश्य क्या है? और दोनों में क्या अंतर है?
जवाबों:
यह एक के रूप में जाना जाता है Shebang
:
http://en.wikipedia.org/wiki/Shebang_(Unix)
#! दुभाषिया [वैकल्पिक- arg]
शेबबैंग केवल तभी प्रासंगिक होता है जब किसी स्क्रिप्ट में निष्पादन की अनुमति हो (जैसे chmod u + x script.sh)।
जब कोई शेल स्क्रिप्ट निष्पादित करता है तो यह निर्दिष्ट दुभाषिया का उपयोग करेगा।
उदाहरण:
#!/bin/bash
# file: foo.sh
echo 1
$ chmod u+x foo.sh
$ ./foo.sh
1
#!
लाइन गिरी (विशेष रूप से, के कार्यान्वयन बताता execve
सिस्टम कॉल) है कि यह कार्यक्रम एक व्याख्या की भाषा में लिखा गया है; निरपेक्ष पथनाम जो दुभाषिया की पहचान करता है। मशीन कोड के लिए संकलित कार्यक्रम एक अलग बाइट अनुक्रम के साथ शुरू होते हैं - अधिकांश आधुनिक यूनिक्स पर, 7f 45 4c 46
( ^?ELF) जो उन्हें इस तरह से पहचानता है।
जब तक आप उस कार्यक्रम को स्क्रिप्ट नहीं मान लेते#!
, तब तक आप जिस भी प्रोग्राम को चाहते हैं, उसके लिए एक पूर्ण मार्ग डाल सकते हैं #!
। कर्नेल के एक आह्वान को फिर से लिखता है
./script arg1 arg2 arg3 ...
जहां से ./script
शुरू होता है, कहते हैं, #! /usr/bin/perl
जैसे कि कमांड लाइन वास्तव में थी
/usr/bin/perl ./script arg1 arg2 arg3
या, जैसा कि आपने देखा है, आप #! /bin/sh
व्याख्या करने के उद्देश्य से एक स्क्रिप्ट लिखने के लिए उपयोग कर सकते हैं sh
।
#!
लाइन केवल यदि आप संसाधित किया जाता है सीधे (स्क्रिप्ट आह्वान ./script
कमांड लाइन पर); फ़ाइल भी निष्पादन योग्य ( chmod +x script
) होनी चाहिए । यदि आप करते हैं sh ./script
तो #!
लाइन आवश्यक नहीं है (और यदि मौजूद है तो इसे नजरअंदाज कर दिया जाएगा), और फ़ाइल को निष्पादन योग्य नहीं होना चाहिए। बिंदु (Do सुविधा का आप को पता है कोई भी भाषा में लिखे गए हैं बिना व्याख्या की भाषा के कार्यक्रमों आह्वान सीधे करने के लिए अनुमति देने के लिए है। grep '^#!' /usr/bin/*
- आपको लगता है कि एक महान कई शेयर कार्यक्रमों इस सुविधा का उपयोग वास्तव में कर रहे हैं पता चल जाएगा।)
इस सुविधा का उपयोग करने के लिए यहां कुछ नियम दिए गए हैं:
#!
बहुत पहले दो होना चाहिए बाइट फ़ाइल में। विशेष रूप से, फ़ाइल को ASCII- संगत एन्कोडिंग में होना चाहिए (जैसे UTF-8 काम करेगा, लेकिन UTF-16 नहीं करेगा) और "बाइट ऑर्डर मार्क" से शुरू नहीं होना चाहिए , या कर्नेल इसे पहचान नहीं पाएगा #!
स्क्रिप्ट।#!
एक पूर्ण पथ होना चाहिए (के साथ शुरू होता है /
)। इसमें स्थान, टैब या न्यूलाइन वर्ण नहीं हो सकते।#!
और के बीच एक स्थान रखना है /
। वहां एक से ज्यादा जगह न रखें।#!
लाइन पर शेल वैरिएबल नहीं डाल सकते हैं , उनका विस्तार नहीं किया जाएगा।#! /usr/bin/awk -f
), कभी-कभी यह सिर्फ उपयोगी होता है ( #! /usr/bin/perl -Tw
)। दुर्भाग्य से, आप निरपेक्ष पथ के बाद दो या अधिक तर्क नहीं रख सकते ।#! /usr/bin/env interpreter
इसके बजाय उपयोग करने के लिए कहेंगे #! /absolute/path/to/interpreter
। यह लगभग हमेशा एक गलती है। यह आपके प्रोग्राम के व्यवहार $PATH
को स्क्रिप्ट के उपयोगकर्ता के चर पर निर्भर करता है। और सभी प्रणालियों env
में पहली जगह नहीं है।setuid
या setgid
विशेषाधिकार का उपयोग नहीं किया जा सकता है #!
; उन्हें मशीन कोड में संकलित किया जाना है। (यदि आप नहीं जानते कि क्या setuid
है, तो इस बारे में चिंता न करें।)इस संबंध में csh
, यह sh
मोटे तौर पर संबंधित है जैसा कि न्यूट्रीमैट एडवांस्ड टी सब्सट्रेट चाय के लिए करता है। इंटरएक्टिव उपयोग के लिए इसके sh
कई फायदे हैं (या बल्कि आधुनिक क्रियान्वयन ने इसे पकड़ लिया है) sh
, लेकिन tcsh
स्क्रिप्टिंग के लिए इसका (या इसके वंशज ) उपयोग करना लगभग हमेशा एक गलती है । यदि आप सामान्य रूप से शेल स्क्रिप्टिंग के लिए नए हैं, तो मैं दृढ़ता से आपको इसे अनदेखा करने और ध्यान केंद्रित करने की सलाह देता हूं sh
। यदि आप एक प्रयोग कर रहे हैं csh
अपना लॉगिन शेल के रूप में रिश्तेदार, करने के लिए स्विच bash
या zsh
, ताकि इंटरैक्टिव कमांड भाषा पटकथा आप कर रहे हैं सीखने की भाषा के रूप में ही किया जाएगा।
#!
; कोई टिप्पणी नहीं कि क्या यह अच्छी शैली है। इस सवाल और हैक के पेशेवरों और विपक्षों की चर्चा के लिए मेरा जवाब देखें #!/usr/bin/env
।
#!/usr/bin/env
राइट थिंग था, लेकिन यह मेरी राय है कि यह लगभग हमेशा एक बुरा विचार है।
यह परिभाषित करता है कि आप अपनी स्क्रिप्ट की व्याख्या / चलाने के लिए किस शेल (कमांड दुभाषिया) का उपयोग कर रहे हैं। प्रत्येक शेल उपयोगकर्ता के साथ इंटरैक्ट करने के तरीके और स्क्रिप्ट्स (प्रोग्राम्स) को निष्पादित करने के तरीके में थोड़ा भिन्न होता है।
जब आप यूनिक्स प्रॉम्प्ट पर एक कमांड टाइप करते हैं, तो आप शेल के साथ इंटरैक्ट कर रहे हैं।
जैसे, #!/bin/csh
सी-शेल, /bin/tcsh
टी-शेल, /bin/bash
बैश शेल आदि को संदर्भित करता है ।
आप बता सकते हैं कि आप किस इंटरएक्टिव शेल का उपयोग कर रहे हैं
echo $SHELL
आदेश, या वैकल्पिक रूप से
env | grep -i shell
आप कमांड के साथ अपने कमांड शेल को बदल सकते हैं chsh
।
प्रत्येक के पास थोड़ा अलग कमांड सेट है और वेरिएबल्स को असाइन करने का तरीका और प्रोग्रामिंग कंस्ट्रक्ट्स का अपना सेट है। उदाहरण के लिए यदि बैश के साथ इफ-स्टेटमेंट अलग दिखता है जो कि सी-शेल में है।
यह पृष्ठ ब्याज के रूप में हो सकता है क्योंकि यह बैश और tcsh कमांड / सिंटैक्स के बीच "अनुवाद" करता है।
शेल स्क्रिप्ट में निर्देश का उपयोग करना आपको एक अलग शेल का उपयोग करके प्रोग्राम चलाने की अनुमति देता है। उदाहरण के लिए, मैं tcsh
शेल को अंतःक्रियात्मक रूप से उपयोग करता हूं , लेकिन अक्सर स्क्रिप्ट फ़ाइल में / बिन / बैश का उपयोग करके बैश स्क्रिप्ट चलाता है।
एक तरफ:
यह अवधारणा अन्य लिपियों तक भी फैली हुई है। उदाहरण के लिए यदि आप पायथन में प्रोग्राम करेंगे तो आप डाल देंगे
#!/usr/bin/python
अपने पायथन कार्यक्रम के शीर्ष पर
#! $SHELL
? क्या यह शेबंग में सही खोल डाल देगा?
!#/bin/bash
निर्देशन की सुंदरता है । यह सिस्टम को बताता है कि आपके शेल स्क्रिप्ट को निष्पादित करने के लिए किस शेल का उपयोग करना है।
$SHELL
जरूरी है कि कौन सा शैल आप इस समय चल रहे हैं बता नहीं करता है; यह सामान्य रूप से आपको आपका डिफ़ॉल्ट शेल बताता है । tcsh सेट $version
और $tcsh
; बैश सेट $BASH_VERSION
। जरूरी नहीं कि सभी गोले एक जैसे ही हों।
#!
लाइन को स्क्रिप्ट के सिंटैक्स से मेल खाना है, न कि जो कोई भी स्क्रिप्ट चला रहा है उसका इस्तेमाल किया गया इंटरेक्टिव शेल।
#!/bin/csh -f
;-f
स्रोत के लिए नहीं खोल बताता उपयोगकर्ता की.login
और.cshrc
है, जो स्क्रिप्ट रन तेजी से बनाता है और उपयोगकर्ता के सेटअप के निर्भरता से बचा जाता है। (या बेहतर अभी तक, csh स्क्रिप्ट न लिखें।)-f
sh या bash स्क्रिप्ट के लिए उपयोग न करें ; इसका एक ही अर्थ नहीं है।