"Bash script.sh" और "./cript.sh" को चलाने में क्या अंतर है?


42

अगर script.sh सिर्फ कुछ विशिष्ट है

#!/bin/bash
echo "Hello World!"

क्या स्क्रिप्ट चलाने का एक पसंदीदा तरीका है? मुझे लगता है कि आपको पहले इसे चोदना होगा ताकि यह निष्पादन योग्य हो जाए?

जवाबों:


56

आपकी विशिष्ट स्क्रिप्ट के लिए या तो रास्ता काम करेगा, सिवाय इसके कि ./script.shनिष्पादन और पठनीय बिट्स की bash script.shआवश्यकता होती है , जबकि केवल पठनीय बिट की आवश्यकता होती है।


अनुमतियों की आवश्यकता के अंतर का कारण आपकी स्क्रिप्ट की व्याख्या करने वाले प्रोग्राम को कैसे लोड किया गया है:

  • ./script.sh आपके शेल को फ़ाइल चलाने के रूप में अगर यह एक नियमित निष्पादन योग्य था बनाता है।

शेल खुद को कांटा करता है और execveफोर्क्ड प्रक्रिया में ऑपरेटिंग सिस्टम को निष्पादित करने के लिए सिस्टम कॉल (जैसे ) का उपयोग करता है । ऑपरेटिंग सिस्टम फ़ाइल की अनुमतियों की जांच करेगा (इसलिए निष्पादन बिट सेट करने की आवश्यकता है) और प्रोग्राम लोडर के अनुरोध को अग्रेषित करता है , जो फ़ाइल को देखता है और निर्धारित करता है कि इसे कैसे निष्पादित किया जाए। लिनक्स में संकलित निष्पादनयोग्य एक ईएलएफ मैजिक नंबर से शुरू होते हैं, जबकि स्क्रिप्ट एक #!( हैशबैंग ) से शुरू होती हैं । हैशबैंग हेडर का मतलब है कि फाइल एक स्क्रिप्ट है और हैशबैंग के बाद निर्दिष्ट प्रोग्राम द्वारा व्याख्या की जानी चाहिए। यह स्क्रिप्ट को सिस्टम को यह बताने की अनुमति देता है कि स्क्रिप्ट की व्याख्या कैसे की जाए।

आपकी स्क्रिप्ट के साथ, प्रोग्राम लोडर कमांड-लाइन तर्क के रूप में निष्पादित /bin/bashऔर पारित करेगा ./script.sh

  • bash script.shकमांड-लाइन तर्क के रूप में आपका शेल रन bashऔर पास script.shकरता है

तो ऑपरेटिंग सिस्टम लोड हो जाएगा bash(यहां तक ​​कि नहीं देख रहा है script.sh, क्योंकि यह सिर्फ एक कमांड-लाइन तर्क है)। बनाई गई bashप्रक्रिया तब व्याख्या करेगी script.shक्योंकि यह कमांड-लाइन तर्क के रूप में पारित हो गया है। क्योंकि script.shकेवल bashएक नियमित फ़ाइल के रूप में पढ़ा जाता है , निष्पादन बिट की आवश्यकता नहीं है।


मैं ./script.shहालांकि उपयोग करने की सलाह देता हूं , क्योंकि आपको नहीं पता होगा कि स्क्रिप्ट की व्याख्या करने वाले को कौन सी आवश्यकता है। तो प्रोग्राम लोडर को आपके लिए निर्धारित करने दें।


3
यदि निष्पादन योग्य बिट सेट नहीं है, तो आप "./script.sh" करके स्क्रिप्ट भी चला सकते हैं
डॉग खाओ बिल्ली दुनिया

1
@ डॉग आप सही हैं। डॉट अंतर्निहित कमांड 'स्रोत' का एक शॉर्टकट है, जो वर्तमान बैश प्रक्रिया में स्क्रिप्ट चलाता है। तो केवल पठनीय बिट की आवश्यकता है।
स्काईडान

5
@Dogeatcatworld जब तक सच है, तब तक दौड़ना . ./script.shएक ही बात नहीं है bash script.sh(या ./script.shस्क्रिप्ट पर विचार करें #!/usr/bin/python -V<newline> print test
केसी

12
सावधान रहें कि स्क्रिप्ट को इंटरेक्टिव सत्र के संदूषण में परिणत किया जा सकता है। उदाहरण के लिए, एक स्क्रिप्ट को PATH पर्यावरण चर को बदलना चाहिए, यह परिवर्तन स्रोत के बाद चलने वाली कमांड को प्रभावित करेगा। यह दृष्टिकोण वास्तव में उन स्थितियों के लिए आरक्षित होना चाहिए जहां आप दुष्प्रभावों (पर्यावरण सेटअप स्क्रिप्ट और पसंद) पर निर्भर करते हैं। अन्य स्थितियों के लिए, जहाँ आप अनुमतियाँ नहीं बदल सकते हैं, कमांड को शेलबैंग लाइन में चलाना, स्क्रिप्ट नाम के बाद सबसे सुरक्षित तरीका है।
ctt

6
ध्यान दें कि, यदि आप वर्तमान निर्देशिका में कोई स्क्रिप्ट बनाते हैं, तो आपको उपयोग करने की आवश्यकता नहीं है । / . ; बस कहो . script.sh। लेकिन मैं उन लोगों से सहमत हूं, जो .स्क्रिप्ट पर कमांड का उपयोग करने को हतोत्साहित करते हैं जो कि उस तरह से लागू होने के लिए नहीं थे। मुझे आश्चर्य है कि किसी ने भी इसका उल्लेख नहीं किया है, यदि स्क्रिप्ट में exitकमांड हैं, और आप इसे स्रोत करते हैं, तो यह आपको लॉग आउट कर सकता है। एक कम गंभीर समस्या यह होगी कि यदि स्क्रिप्ट ए करता है cd, क्योंकि यह माता-पिता (इंटरैक्टिव) शेल को भी प्रभावित करेगा।
स्कॉट

18

bash script.shसीधे बैश का उपयोग करके स्क्रिप्ट को आमंत्रित करता है। निष्पादित करने के तरीके को निर्धारित करने के लिए
./script.shशेबंग का उपयोग कर रहा है #!/bin/bash

यदि आप वास्तव में जानना चाहते हैं, तो यदि आप ऐसा करते हैं तो बाइनरी निष्पादित bash script.shहोती है which bash

तो आपके उदाहरण में इससे कोई फर्क नहीं पड़ता। हां, आपको chmod +x script.shइसे सीधे निष्पादित करने में सक्षम होना होगा ./script.sh


2
खैर, इससे कोई फर्क नहीं पड़ता है कि /bin/bashयह bashआपके में पहला है $PATH
cjm

आप सही हे। और #!/bin/bash/bin/bash
शेबंग

मेरे सिस्टम पर बैश (संस्करण 4.2.37) निष्पादन बिट सेट के बिना भी स्क्रिप्ट निष्पादित करता है। आप क्यों कहते हैं कि निष्पादन की आवश्यकता है?
5

हां, निष्पादन बिट की आवश्यकता केवल चालान के माध्यम से होती है ./script.sh
xx4h

4

इस तरह से एक फ़ाइल Delete_Self.sh बनाएँ:

 #!/bin/rm

 echo I am still here!

इस स्क्रिप्ट को चलाएं क्योंकि sh Delete_Self.shआप देखेंगे कि "मैं अभी भी यहाँ हूँ!" गूँज उठा।

इसे निष्पादन योग्य बनाएं, और इसे चलाएं जैसा कि ./Delete_Self.shआप देखेंगे कि कुछ भी वापस नहीं गूंज रहा है, जबकि फ़ाइल Delete_Self.shस्वयं चली गई है।

तो अंतर यह है कि:

  • bash script.sh# की अनदेखी करेंगे! लाइन, क्योंकि bash को स्क्रिप्ट चलाने के कार्यक्रम के रूप में निर्दिष्ट किया गया है।
  • ./script.sh# पढ़ लेंगे! चलाने के लिए कार्यक्रम निर्धारित करने के लिए लाइन script.sh

अच्छा उदाहरण के लिए +1
इटारूग

1

अन्य उत्तरों के अलावा, ./script.sh(i) और स्रोत ./script.sh(ii) के माध्यम से स्क्रिप्ट चलाने के बीच के अंतर को जानना उपयोगी है - (i) संस्करण कमांड को चलाने के लिए एक नया शेल बनाता है, जबकि (ii) इसे चलाता है। वर्तमान शेल - जो अनिवार्य हो सकता है अगर निष्पादन योग्य परिवर्तन पर्यावरण चर जो निष्पादन योग्य निकास के बाद संरक्षित किए जाने की आवश्यकता है। उदाहरण के लिए, एक अजगर कोंडा पर्यावरण को सक्रिय करने के लिए निम्नलिखित का उपयोग किया जाना चाहिए:

source activate my_env

एनबी एक और विकल्प है sourceजिसका आप सामना कर सकते हैं वह है .बिलिन, यानी

. activate my_env
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.