"स्रोत x", "के बीच अंतर क्या है। x ”और“ ./x ”बैश में?


11

मैं एक bash स्रोत run.shनिम्नानुसार है,

#!/bin/bash
if [ $# -ne 1 ]; then
    exit
fi
...

जब मैं इसे दो तरीकों से निष्पादित करता हूं, तो अलग-अलग व्यवहार होते हैं। पहला तरीका है,

source run.sh

यह निष्पादन के बाद टर्मिनल को बंद कर देगा। दूसरा तरीका है,

./run.sh

यह केवल स्क्रिप्ट चलाने का काम पूरा करेगा, और टर्मिनल पर रहेगा। मैं पूछ रहा हूं कि क्या दोनों के लिए बैश स्क्रिप्ट से बाहर निकलने source run.shऔर ./run.shअमल करने की आज्ञा है । मैंने भी कोशिश की returnहै, जो ./run.shनिष्पादन के तहत अच्छी तरह से काम नहीं करता है ।

आमतौर पर, मुझे दिलचस्पी है कि ऐसा क्यों हो रहा है, और "स्रोत" और "का उपयोग करने में क्या अंतर है।" स्क्रिप्ट निष्पादन के लिए?

जवाबों:


16

जवाब देने से पहले, मुझे लगता है कि कुछ स्पष्टीकरण की आवश्यकता है। आइए निम्नलिखित तीन पंक्तियों का विश्लेषण करें:

source run.sh
. run.sh
./run.sh

पहली दो पंक्तियाँ बिल्कुल समान हैं: .वास्तव में इसके लिए एक उपनाम है sourcesourceवर्तमान संदर्भ में शेल स्क्रिप्ट को निष्पादित करने के लिए क्या होता है, इसलिए exitशेल को छोड़ने का आह्वान किया जाएगा।

तीसरी पंक्ति (जो आपको भ्रमित करती है) का अन्य रेखाओं से कोई लेना देना नहीं है। ./run.shसिर्फ एक रास्ता है, और के रूप में (उदाहरण के लिए) एक ही है /home/user/run.shया /usr/bin/something। हमेशा याद रखें कि शेल में कमांड एक स्थान से अलग हो जाते हैं। तो, इस मामले में, कमांड नहीं है ., लेकिन यह है ./run.sh: इसका मतलब है कि एक उप-शेल निष्पादित किया exitजाएगा और यह कि उप-शेल पर प्रभाव पड़ेगा।


5

तीन तरीके से:

आप किसी फ़ंक्शन में स्क्रिप्ट संलग्न कर सकते हैं और केवल वापसी का उपयोग कर सकते हैं।

#!/usr/bin/env bash
main() {
    ...
    return 1
    ...
}
main "$@"

आप परीक्षण कर सकते हैं कि क्या स्क्रिप्ट को एक इंटरैक्टिव शेल द्वारा सॉर्ट किया जा रहा है।

if [[ $- = *i* ]]; then
    return 1
else
    exit 1
fi

आप वापसी करने की कोशिश कर सकते हैं, और यदि यह विफल रहता है, तो बाहर निकलें।

return 1 2>/dev/null || exit 1

कोई संकेत के रूप में कैसे जादू भस्म $- = *i* काम करता है?
deadbeef404

@ deadbeef404 विशेष पैरामीटर -वर्तमान में सक्रिय विकल्प झंडे रखता है। परीक्षण जाँचता है कि -iझंडा सक्रिय है या नहीं। Gnu.org/software/bash/manual/html_node/Special-Parameters.html
geirha

1

कमांड 'सोर्स' को 'इन्क्लूड' स्टेटमेंट की तरह समझें। यह तर्क की सामग्री लेता है और इसे चलाता है जैसे कि इसे सीधे चलाया गया था। इस स्थिति में आपका कमांड 'run.sh' के तर्क के साथ 'source' है और run.sh को ठीक वैसे ही निष्पादित किया जाता है, जैसे आपने run.sh की सामग्री को अपनी कमांड लाइन में टाइप किया था।

जब आप './run.sh' चलाते हैं, './run.sh' आपकी आज्ञा है और इसका कोई तर्क नहीं है। चूंकि यह फ़ाइल सादा-पाठ है और बाइनरी नहीं है, इसलिए आपका शेल शेलबैंग में एक दुभाषिया की तलाश में है (पहली पंक्ति में '#') और '/ बिन / बैश' पाता है। तो आपका शेल फिर बैश का एक नया उदाहरण शुरू करता है और रन.श की सामग्री को इस नए इंस्टेंस के अंदर चलाया जाता है।

पहले उदाहरण में, जब बैश 'एक्जिट' कमांड पर पहुंचता है, तो इसे ठीक उसी तरह निष्पादित किया जाता है, जैसे आपने इसे कमांड लाइन में टाइप किया था। दूसरे उदाहरणों में इसे bash प्रक्रिया में निष्पादित किया जाता है, जब आपका शेल प्रारंभ हुआ, इस प्रकार केवल bash के इस उदाहरण को एक 'एग्जिट' कमांड प्राप्त होती है।

जब आप एक पंक्ति को बैश में टाइप करते हैं, तो पहले स्थान के पहले कुछ भी एक कमांड के रूप में व्यवहार किया जाता है और कुछ भी जो निम्न प्रकार से तर्क के रूप में माना जाता है। आदेश '।' 'स्रोत' का एक उपनाम है। जब तुम दौड़ते हो ’। run.sh 'the'। ' यह अपने आप में एक आदेश है क्योंकि यह अंतरिक्ष से तर्क से अलग है। जब आप './run.sh' चलाते हैं, तो आपका आदेश '/ .run.sh' और '' है। 'के साथ चलाने के लिए रिश्तेदार पथ का हिस्सा है।' अपने वर्तमान फ़ोल्डर का प्रतिनिधित्व।


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