2017-01-25 7 views
5

मेरे पूर्व सहयोगी द्वारा बैश में लिखे गए एक प्रोजेक्ट पर काम करते हुए, मैंने देखा कि सभी .sh फ़ाइलों में कुछ भी नहीं है लेकिन कार्य परिभाषाएं #!/bin/false से शुरू होती हैं, जैसा कि मैं समझता हूं, केवल-फाइलों को निष्पादित करने से रोकने की सुरक्षा तंत्र।बैश स्क्रिप्ट में #!/Bin/false का उद्देश्य

उदाहरण:

my_foo.sh

#!/bin/false 
function foo(){ 
    echo foontastic 
} 

my_script.sh

#!/bin/bash 

./my_foo.sh # does nothing 
foo # error, no command named "foo" 

. ./my_foo.sh 
foo # prints "foontastic" 

हालांकि जब मैं #!/bin/false का उपयोग नहीं करते, दोनों उचित और अनुचित उपयोग के प्रभाव वास्तव में कर रहे हैं वही:

उदाहरण:

my_bar.sh

function bar(){ 
    echo barvelous 
} 

my_script.sh

#!/bin/bash 

./my_bar.sh # spawn a subshell, defines bar and exit, effectively doing nothing 
bar # error, no command named "bar" 

. ./my_bar.sh 
bar # prints "barvelous" 

के बाद ठीक से दोनों ही मामलों में source साथ उन्हें शामिल होने की उम्मीद काम करता है के रूप में से उन स्क्रिप्ट का उपयोग कर, और में उन्हें क्रियान्वित दोनों मामले माता-पिता के खोल के परिप्रेक्ष्य से कुछ भी नहीं करते हैं और अमान्य उपयोग से संबंधित कोई त्रुटि संदेश उत्पन्न नहीं करते हैं, उन स्क्रिप्ट में #!/bash/false का बिल्कुल सही उद्देश्य क्या है?

+2

है तुम खुद कहा: 'FALSE' कुटिया के साथ, सामग्री निष्पादित नहीं है। यह एक सुरक्षा है, यदि गलत संदर्भ में उपयोग किया जाता है या भारी संसाधनों का उपयोग करते समय स्क्रिप्ट त्रुटि-प्रवण होती है। सबसे अधिक संभावना है, यह एक आदत है जिसे आपके सहयोगी ने उठाया है, जिसका अधिकांश मामलों में कोड पर कोई प्रभाव नहीं पड़ता है, लेकिन यह अधिक जटिल परिस्थितियों में उपयोगी हो सकता है। – Aserre

+0

इसके अलावा यह ध्यान देने योग्य होना चाहिए कि, जब वह शैल दुभाषिया को सीधे 'bash my_script.sh' के रूप में आमंत्रित करती है तो वह-बैंग लाइन '#!/Bin/true' या' #!/Bin/false' का स्क्रिप्ट पर कोई प्रभाव नहीं पड़ता है। ', यह वाक्यविन्यास' bash' के साथ स्क्रिप्ट चलाता है, इससे कोई फर्क नहीं पड़ता कि आउटपुट 'foontastic' – Inian

+2

'।/my_bar.sh' एक सबहेल नहीं बनाता है: यह एक नया नया खोल बनाता है। यह सिर्फ एक तकनीकीता नहीं है: सबहेल को मुख्य खोल के सभी चरों की एक प्रति प्राप्त होती है (जिनमें वे निर्यात के लिए चिह्नित नहीं हैं), जबकि एक अलग खोल केवल निर्यात किए गए चर प्राप्त करता है। सब्सक्रिप्शन अन्य तरीकों से लॉन्च किए जाते हैं, उदाहरण के लिए कथन कोष्ठक '() ', पाइप शुरू करना',', प्रक्रिया/कमांड प्रतिस्थापन '$()' '<()' '>()'। – Fred

उत्तर

4

सामान्य तौर पर, के बैश कोड के साथ एक फ़ाइल testcode पर विचार यह

आप इसके साथ तीन अलग-अलग कर सकते हैं में करते हैं:

$ ./testcode 
You are executing ./testcode 

यह काम करता है अगर testcode और सही अनुमतियां है सही Shebang। #!/bin/false के शेबैंग के साथ, यह कुछ भी आउटपुट नहीं करता है और 1 (झूठा) का कोड देता है।

$ bash ./testcode 
You are executing ./testcode 

यह पूरी तरह से मामला (जो भी लापता जा सकता है) की उपेक्षा और यह केवल पढ़ने की अनुमति, नहीं निष्पादन योग्य अनुमति की आवश्यकता है। विंडोज़ में सीएमडी कमांड लाइन से बैश स्क्रिप्ट को कॉल करने का यह तरीका है (यदि आपके पास अपने पाथ में bash.exe है ...), क्योंकि वहां शेबैंग मशीनीवाद काम नहीं करता है।

$ . ./testcode 
You are sourcing ./testcode 

यह भी पूरी तरह से, कुटिया की उपेक्षा के रूप में ऊपर है, लेकिन यह एक पूर्ण अलग बात है क्योंकि एक स्क्रिप्ट मतलब है वर्तमान खोल यह पर अमल होने सोर्सिंग, जबकि एक स्क्रिप्ट को क्रियान्वित करने प्रेरक का मतलब इसे निष्पादित करने के लिए एक नया खोल। उदाहरण के लिए, यदि आप एक sourced स्क्रिप्ट में exit कमांड डालते हैं, तो आप वर्तमान खोल से बाहर निकलते हैं, जो शायद ही कभी आप चाहते हैं। इसलिए, सोर्सिंग अक्सर फ़ंक्शन परिभाषाओं या स्थिरांक को लोड करने के लिए उपयोग की जाती है, कुछ हद तक import अन्य प्रोग्रामिंग भाषाओं के बयान जैसा दिखता है, और विभिन्न प्रोग्रामर निष्पादित होने वाली स्क्रिप्ट के बीच अंतर करने के लिए अलग-अलग आदतें विकसित करते हैं और में फ़ाइलों को शामिल किया जाता है। मैं आमतौर पर पूर्व के लिए किसी भी एक्सटेंशन का उपयोग नहीं करता (अन्य .sh का उपयोग करते हैं), लेकिन मैं बाद के लिए .shinc का विस्तार का उपयोग करता हूं। आपके पूर्व सहयोगी ने #!/bin/false का शेबैंग इस्तेमाल किया और कोई केवल उनसे पूछ सकता है कि उन्होंने इसे एक अरब अन्य संभावनाओं के लिए क्यों पसंद किया। एक कारण यह है कि मेरे दिमाग में आता है कि आप file उपयोग कर सकते हैं के अलावा इन फ़ाइलों को बताने के लिए है:,

$ file testcode testcode2 
testcode: Bourne-Again shell script, ASCII text executable 
testcode2: a /bin/false script, ASCII text executable 
बेशक

यदि इन में शामिल फ़ाइलों को केवल कार्यशील परिभाषाएँ होते हैं, यह उन्हें निष्पादित करने के लिए हानिरहित है, तो मुझे नहीं लगता कि आपके सहयोगी ने इसे निष्पादन को रोकने के लिए किया था।

मेरा एक अन्य आदत, पायथन दुनिया से प्रेरित है, मेरे .shinc फ़ाइलों के अंत में कुछ प्रतिगमन परीक्षण जगह (कम से कम है, जबकि विकासशील)

... function definitions here ... 

[ "$0" != "${BASH_SOURCE[0]}" ] && return 

... regression tests here ... 

return के बाद से निष्पादित स्क्रिप्ट में कोई त्रुटि उत्पन्न करता है, लेकिन sourced लिपियों में ठीक है, एक ही परिणाम प्राप्त करने के लिए एक और अधिक गुप्त रास्ता

... function definitions here ... 

return 2>/dev/null || : 

... regression tests here ... 
1

#!/bin/false का उपयोग करने में अंतर या पैरेंट खोल के बिंदु से नहीं, रिटर्न कोड में है।

/bin/false हमेशा एक असफल रिटर्न कोड लौटाता है (मेरे मामले में 1, लेकिन यह सुनिश्चित नहीं है कि यह मानक है)।

कि प्रयास करें:

./my_foo.sh //does nothing 
echo $? // shows "1", a.k.a failing 

./my_bar.sh //does nothing 
echo $? // shows "0", a.k.a. everything went right 

तो, का उपयोग कर #!/bin/false न केवल तथ्य यह है कि स्क्रिप्ट निष्पादित करने के लिए इरादा नहीं है दस्तावेजों, लेकिन ऐसा करते हुए भी एक त्रुटि वापसी कोड पैदा करता है।

+0

आपका दूसरा उदाहरण सही नहीं है, अगर my_bar.sh में "निकास 1" है। साथ ही निष्पादित करने के बजाए उन फ़ाइलों को भी शामिल किया गया है ("./my_foo", "./my_bar") वापसी मान वास्तव में अंतिम निष्पादित कमांड का वापसी मान है, इसलिए वापसी मूल्यों को सुरक्षा के रूप में उपयोग करने के लिए मुझे सभी को समाप्त करना होगा 'सत्य' के साथ केवल स्क्रिप्ट शामिल करें। –

+0

ओपी द्वारा लिखित 'my_bar.sh' स्क्रिप्ट' में 'exit' कमांड शामिल नहीं है। इसके अलावा, रिटर्न कोड केवल स्क्रिप्ट का रिटर्न कोड है। मुद्दा यह है कि '#!/Bin/false' का उपयोग करके एक गलत रिटर्न कोड उत्पन्न होगा। –

+0

मैनुअल के अनुसार: 'झूठी - कुछ भी नहीं, असफल' – ash

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