बश लिपि बनाम इसे सोर्स करने के बीच अंतर क्या है?


जवाबों:


344

संक्षिप्त जवाब

एक स्क्रिप्ट सोर्सिंग वर्तमान शेल प्रक्रिया में कमांड चलाएगा ।

एक स्क्रिप्ट को निष्पादित करने से एक नई शेल प्रक्रिया में कमांड चलेंगे ।

यदि आप स्क्रिप्ट को अपने वर्तमान में चल रहे शेल में पर्यावरण को बदलना चाहते हैं, तो स्रोत का उपयोग करें। अन्यथा निष्पादित करें।

यदि आप अभी भी भ्रमित हैं, तो कृपया पर पढ़ें।

शब्दावली

निष्पादित करने के लिए सिंटैक्स और सिंटैक्स के बारे में कुछ सामान्य भ्रम को स्पष्ट करने के लिए:

./myscript

यह निष्पादित करेगा myscriptबशर्ते कि फ़ाइल निष्पादन योग्य हो और वर्तमान निर्देशिका में स्थित हो। प्रमुख डॉट और स्लैश ( ./) वर्तमान निर्देशिका को दर्शाता है। यह आवश्यक है क्योंकि वर्तमान निर्देशिका आमतौर पर (और आमतौर पर नहीं होनी चाहिए) में नहीं है $PATH

myscript

यह निष्पादित करेगा myscriptयदि फ़ाइल निष्पादन योग्य है और कुछ निर्देशिका में स्थित है $PATH

source myscript

यह स्रोत होगा myscript। फ़ाइल को निष्पादन योग्य नहीं होना चाहिए लेकिन यह एक मान्य शेल स्क्रिप्ट होनी चाहिए। फ़ाइल वर्तमान निर्देशिका में या किसी निर्देशिका में हो सकती है $PATH

. myscript

यह भी स्रोत होगा myscript। यह "वर्तनी" आधिकारिक एक है जैसा कि पोसिक्स द्वारा परिभाषित किया गया है । बैश sourceको एक उपनाम के रूप में परिभाषित किया गया डॉट।

प्रदर्शन

myscript.shनिम्नलिखित सामग्री पर विचार करें :

#!/bin/sh
# demonstrate setting a variable
echo "foo: "$(env | grep FOO)
export FOO=foo
echo "foo: "$(env | grep FOO)
# demonstrate changing of working directory
echo "PWD: "$PWD
cd somedir
echo "PWD: "$PWD

इससे पहले कि हम स्क्रिप्ट पर अमल करें, पहले हम वर्तमान परिवेश की जाँच करें:

$ env | grep FOO
$ echo $PWD
/home/lesmana

चर FOOपरिभाषित नहीं है और हम होम डायरेक्टरी में हैं।

अब हम फ़ाइल को निष्पादित करते हैं:

$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir

पर्यावरण को फिर से जांचें:

$ env | grep FOO
$ echo $PWD
/home/lesmana

चर FOOसेट नहीं है और कार्यशील निर्देशिका नहीं बदली है।

स्क्रिप्ट आउटपुट स्पष्ट रूप से दिखाता है कि चर सेट किया गया था और निर्देशिका को बदल दिया गया था। बाद में जांच से पता चलता है कि चर सेट नहीं है और निर्देशिका नहीं बदली गई है। क्या हुआ? बदलाव एक नए खोल में किए गए थे । वर्तमान खोल एक पैदा की नई स्क्रिप्ट चलाने के लिए खोल। स्क्रिप्ट नए शेल में चल रही है और पर्यावरण में सभी परिवर्तन नए शेल में प्रभावी होते हैं। स्क्रिप्ट होने के बाद नया शेल नष्ट हो जाता है। नए शेल में पर्यावरण के सभी परिवर्तन नए शेल के साथ नष्ट हो जाते हैं। वर्तमान शेल में केवल आउटपुट टेक्स्ट ही प्रिंट होता है।

अब हम फ़ाइल का स्रोत :

$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir

पर्यावरण को फिर से जांचें:

$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir

चर FOO सेट है और कार्य निर्देशिका बदल गई है।

स्क्रिप्ट को सोर्स करने से नया शेल नहीं बनता है। सभी कमांड वर्तमान शेल में चलाए जाते हैं और पर्यावरण में परिवर्तन वर्तमान शेल में प्रभावी होते हैं।

ध्यान दें कि इस सरल उदाहरण में निष्पादन की आउटपुट स्क्रिप्ट की सोर्सिंग के समान है। जरूरी नहीं कि हमेशा ऐसा ही हो।

एक और प्रदर्शन

निम्नलिखित स्क्रिप्ट पर विचार करें pid.sh:

#!/bin/sh
echo $$

(विशेष चर $$मौजूदा चल रहे शेल प्रक्रिया के पीआईडी ​​तक विस्तारित होता है)

पहले वर्तमान शेल का पीआईडी ​​प्रिंट करें:

$ echo $$
25009

स्रोत स्क्रिप्ट:

$ source pid.sh
25009

स्क्रिप्ट निष्पादित करें, पीआईडी ​​पर ध्यान दें:

$ ./pid.sh
25011

स्रोत फिर से:

$ source pid.sh
25009

फिर से निष्पादित करें:

$ ./pid.sh
25013

आप देख सकते हैं कि स्क्रिप्ट को निष्पादित करते समय स्क्रिप्ट को एक ही प्रक्रिया में चलाना एक नई प्रक्रिया बनाता है। वह नई प्रक्रिया नया खोल है जिसे स्क्रिप्ट के निष्पादन के लिए बनाया गया था। स्क्रिप्ट को सोर्स करने से एक नया शेल नहीं बनता है और इस तरह पीआईडी ​​एक ही रहता है।

सारांश

स्क्रिप्ट को सोर्स करने और निष्पादित करने वाले दोनों स्क्रिप्ट लाइन में कमांड को लाइन से चलाएंगे, जैसे कि आपने उन कमांड को लाइन से लाइन द्वारा टाइप किया था।

अंतर हैं:

  • जब आप उस स्क्रिप्ट को निष्पादित करते हैं जिसे आप एक नया शेल खोल रहे हैं, तो नए शेल में कमांड टाइप करें, आउटपुट को अपने वर्तमान शेल पर वापस कॉपी करें, फिर नए शेल को बंद करें। पर्यावरण में कोई भी परिवर्तन केवल नए शेल में प्रभावी होगा और नया शेल बंद होने के बाद खो जाएगा।
  • जब आप स्क्रिप्ट का स्रोत बनाते हैं तो आप अपने वर्तमान शेल में कमांड टाइप कर रहे होते हैं । पर्यावरण में कोई भी परिवर्तन प्रभावी होगा और आपके वर्तमान शेल में रहेगा।

यदि आप स्क्रिप्ट को अपने वर्तमान में चल रहे शेल में पर्यावरण को बदलना चाहते हैं, तो स्रोत का उपयोग करें। अन्यथा निष्पादित करें।


यह सभी देखें:


2
सोर्सिंग का एक उपयोग आपकी स्क्रिप्ट के लिए कॉन्फ़िगरेशन फ़ाइल का एक अल्पविकसित रूप बना रहा है। आप डिफ़ॉल्ट मानों के लिए विभिन्न चर सेट करके शुरू करते हैं, और फिर कुछ myscript.conf जैसे स्रोत में - और उस खट्टी स्क्रिप्ट में असाइनमेंट स्टेटमेंट हो सकते हैं जो आपके द्वारा इच्छित मानों को ओवरराइड करते हैं। चूंकि खटारा स्क्रिप्ट # / bin / bash से शुरू नहीं होती है इसलिए इसे सीधे निष्पादित करने के लिए प्रोत्साहित नहीं किया जाता है।
लॉरेंस

इसलिए स्रोत इसे वैश्विक दायरे में चलाने की तरह है, और इसे निष्पादित करने से एक नया स्थानीय क्षेत्र बनता है। क्या इसे एक स्क्रिप्ट में एक फ़ंक्शन तक बढ़ाया जा सकता है? एक समारोह (सामान्य रूप से) या "स्रोत" इसे निष्पादित करने के लिए?
अल्टेराल्मिंड

2
क्या उपयोग करने source myscript.shऔर के बीच कोई अंतर है . myscript.sh?
होलोले

2
यदि बैश का उपयोग कर रहे हैं तो व्यावहारिक रूप से कोई अंतर नहीं है। bash में स्रोत एक उपनाम है।
22

1
मुझे यह पसंद है जब लोग इस तरह के विस्तृत उदाहरण प्रदान करते हैं, ताकि खुद जैसे लिनक्स के नवाबी लोग भी समझ सकें। धन्यवाद!
जूलियस

21

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

किसी स्क्रिप्ट को सोर्स करने का मतलब है कि उसे वर्तमान शेल द्वारा ही पार्स और निष्पादित किया जाता है। यह ऐसा है जैसे आपने स्क्रिप्ट की सामग्री टाइप की है। इस कारण से, स्क्रिप्ट को अलग किए जाने की आवश्यकता निष्पादन योग्य नहीं है। लेकिन यह निष्पादन योग्य है अगर आप इसे निष्पादित कर रहे हैं।

यदि आपके पास वर्तमान शेल में स्थितीय तर्क हैं, तो वे अपरिवर्तित हैं।

तो अगर मेरे पास कोई फ़ाइल है a.sh:

echo a $*

और मैं करता हूँ:

$ set `date`
$ source ./a.sh

मुझे कुछ ऐसा मिलता है:

a Fri Dec 11 07:34:17 PST 2009

जहाँ तक:

$ set `date`
$ ./a.sh

मुझे देता है:

a

उम्मीद है की वो मदद करदे।


5
यद्यपि यह उत्तर हर तरह से सही है, लेकिन मुझे यह समझना बहुत कठिन लगता है क्योंकि यह एक अन्य अवधारणा (स्थितिगत मापदंडों की स्थापना) का उपयोग करके प्रदर्शित किया जाता है, जो कि, मेरी राय में, सोर्सिंग और खुद को निष्पादित करने के अंतर से भी अधिक भ्रामक है।
लीमैन

9

सोर्सिंग अनिवार्य रूप से स्क्रिप्ट की प्रत्येक पंक्ति को कमांड प्रॉम्प्ट पर एक बार टाइप करने के समान है ...

निष्पादन एक नई प्रक्रिया शुरू करता है और फिर स्क्रिप्ट की प्रत्येक पंक्ति चलाता है, केवल वर्तमान वातावरण को संशोधित करता है कि वह क्या देता है।


6

उपरोक्त के अलावा, स्क्रिप्ट ./myscriptको निष्पादित करने के लिए फ़ाइल myscript के लिए निष्पादन की अनुमति की आवश्यकता होती है जबकि सोर्सिंग के लिए किसी भी निष्पादित अनुमति की आवश्यकता नहीं होती है। इसलिए chmod +x myscriptपहले की आवश्यकता नहीं हैsource myscript


2
सच है, लेकिन अगर यह समस्या है, तो आप हमेशा भाग सकते हैं bash myscript
डैनियल बेक

5

सोर्सिंग आपको स्क्रिप्ट में परिभाषित सभी अतिरिक्त चर मिलते हैं।
इसलिए यदि आपके पास परिभाषाएँ हैं या कार्य करना है, तो आपको स्रोत और निष्पादन नहीं करना चाहिए। अभिभावक पर्यावरण से स्वतंत्र हैं।


3

अगर मुझे सही याद है, तो स्क्रिप्ट को निष्पादित करना स्क्रिप्ट #!फ़ाइल के साथ एक तर्क के रूप में निष्पादन योग्य चलाता है (आमतौर पर एक नया शेल शुरू करना और स्क्रिप्ट को नए शेल में प्रभावी रूप से सोर्स करना, जैसा कि #!/bin/sh);
जबकि, स्क्रिप्ट की सोर्सिंग आपके वर्तमान शेल वातावरण में प्रत्येक लाइन को निष्पादित करती है, जो आपके वर्तमान शेल को म्यूट करने के लिए उपयोगी है (उदाहरण के लिए, शेल फ़ंक्शंस और निर्यात पर्यावरण चर को परिभाषित करने का एक तरीका प्रदान करना)।


2

sourceकमांड वर्तमान शेल वातावरण में प्रदान की गई स्क्रिप्ट (निष्पादन योग्य अनुमति अनिवार्य नहीं है ) को निष्पादित करता है , जबकि नए शेल में प्रदान की गई निष्पादन योग्य स्क्रिप्ट को निष्पादित करता है ।./

इसके अलावा, उदाहरण के लिए इस उत्तर की जाँच करें: https://superuser.com/a/894748/432100

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