बैश स्क्रिप्ट से बाहर निकलने का कोई भी तरीका, लेकिन टर्मिनल को छोड़ना नहीं


183

जब मैं exitशेल स्क्रिप्ट में कमांड का उपयोग करता हूं , तो स्क्रिप्ट टर्मिनल (प्रॉम्प्ट) को समाप्त कर देगी। क्या किसी स्क्रिप्ट को समाप्त करने और फिर टर्मिनल में रहने का कोई तरीका है?

मेरी स्क्रिप्ट के run.shसीधे तौर पर निष्पादित होने, या किसी अन्य स्क्रिप्ट से स्रोत से निष्पादित होने की उम्मीद है।

संपादित करें: अधिक विशिष्ट होना करने के लिए, वहाँ दो लिपियों हैं run2.shके रूप में

...
. run.sh
echo "place A"
...

और के run.shरूप में

...
exit
...

जब मैं इसे चलाता हूं . run2.sh, और अगर यह exitकोडलाइन को हिट करता है run.sh, तो मैं चाहता हूं कि यह टर्मिनल पर रुके और वहां रहे। लेकिन इस्तेमाल exitकरने से पूरा टर्मिनल बंद हो जाता है।

पुनश्च: मैंने उपयोग करने की कोशिश की है return, लेकिन echoकोडलाइन अभी भी निष्पादित होगी ...।


5
मुझे वास्तव में, वास्तव में, वास्तव में पूछना है: आप एक खट्टा स्क्रिप्ट में निकास का उपयोग क्यों कर रहे हैं?
इग्नासियो वाज़क्वेज़-अब्राम्स

3
निकास आदेश आपके टर्मिनल सत्र / लॉगिन को समाप्त नहीं करना चाहिए। यदि आप exit 0सफलता के बाद स्क्रिप्ट को समाप्त करने के लिए उपयोग करते हैं, जब आप अपनी स्क्रिप्ट को चलाते हैं: ./test.shआपको आउटपुट देखना चाहिए, लेकिन आपका कंसोल खुला रहेगा।
बेन एश्टन

आप shellकमांड का उपयोग कर सकते हैं , जो वास्तव में एक शेल टर्मिनल खोलता है। मेरा अपना अनुभव यह है कि ऐसा नहीं होता है exit। बाहर निकलें सामान्य रूप से मूल स्क्रिप्ट पर नियंत्रण वापस देता है।
विलेम वैन ओनसेम

जवाबों:


258

"समस्या" वास्तव में है कि आप सोर्सिंग कर रहे हैं और स्क्रिप्ट निष्पादित नहीं कर रहे हैं। जब आप किसी फ़ाइल को स्रोत करते हैं, तो उसकी सामग्री को सब-स्पॉन के बजाय वर्तमान शेल में निष्पादित किया जाएगा। इसलिए, निकास सहित सब कुछ, वर्तमान शेल को प्रभावित करेगा।

उपयोग करने के बजाय exit, आप उपयोग करना चाहेंगे return


2
यहाँ एक और व्याख्या है जो मुझे सहायक
लगी

हालांकि सही है, यह एक महान जवाब नहीं है। यह अनदेखा करता है कि कॉलिंग स्क्रिप्ट चर या फ़ंक्शन की घोषणा कर सकती है जिसे स्क्रिप्ट की पहुंच की आवश्यकता है। बेहतर होगा कि रिटर्न कोड कैसे सेट किया जाए और फिर runs.sh@ruakh में इसे प्रोसेस किया जाए तो इस सवाल का बेहतर जवाब होगा।
माइकस्किंकेल 17

5
क्या होगा अगर फ़ंक्शन एक नेस्टेड कॉल है? यानी कॉल बी, बी कॉल सी, सी तुरंत ए और बी से बाहर निकलना चाहता है।
माइकल

सोर्स लगभग कॉपी पेस्ट जैसा ही है। इसका उपयोग करना बेहतर है sh <script>या bash <script>यदि कोई स्क्रिप्ट चलाना चाहता है और किसी बिंदु पर समाप्त करना चाहता है
पेटेरकुला 20

42

हाँ; आप उपयोग कर सकते हैं returnके बजाय exit। इसका मुख्य उद्देश्य शेल फ़ंक्शन से वापस लौटना है, लेकिन यदि आप इसका उपयोग किसी sourcedd स्क्रिप्ट में करते हैं, तो यह उस स्क्रिप्ट से वापस आ जाता है।

के रूप में की §4.1 "बॉर्न शैल Builtins" बैश संदर्भ मैनुअल डालता है यह:

     return [n]

वापसी मान n से बाहर निकलने के लिए शेल फ़ंक्शन का कारण । यदि n की आपूर्ति नहीं की जाती है, तो रिटर्न वैल्यू फ़ंक्शन में निष्पादित अंतिम कमांड की निकास स्थिति है। यह भी साथ निष्पादित किया जा रहा एक स्क्रिप्ट के निष्पादन समाप्त करने के लिए इस्तेमाल किया जा सकता .है (या sourceतो लौटने) निर्मित, एन या स्क्रिप्ट के निकास स्थिति के रूप में स्क्रिप्ट के भीतर क्रियान्वित पिछले आदेश के निकास स्थिति। RETURNफ़ंक्शन या स्क्रिप्ट के बाद निष्पादन शुरू होने से पहले ट्रैप से जुड़ी किसी भी कमांड को निष्पादित किया जाता है। वापसी स्थिति गैर शून्य है अगर returnएक समारोह के बाहर और नहीं द्वारा एक स्क्रिप्ट के निष्पादन के दौरान प्रयोग किया जाता है .या source


3
returnकेवल एक फ़ंक्शन से उपयोग किया जा सकता है। आप का उपयोग करते हैं returnऔर एक खोल स्क्रिप्ट (जैसे के रूप में यह अमल sh run.sh-), बैश एक त्रुटि रिपोर्ट करेंगे return: can only एक समारोह से लौटने 'या sourced script`
Tzunghsing डेविड वोंग

@TzungsingDavidWong: आपको लगता है कि इस उत्तर का थोक आधिकारिक संदर्भ मैनुअल से एक उद्धरण है? और आपके द्वारा उद्धृत त्रुटि-संदेश आपके दावे के बजाय इस उत्तर से सहमत हैं?
बरबाद

l मैं आपसे असहमत नहीं हूँ। मैं केवल यह बताना चाहता हूं कि returnयदि स्क्रिप्ट शेल स्क्रिप्ट के रूप में चलाई जाती है और निष्पादित नहीं होती है तो यह काम नहीं करेगा। (या source)। BTW, मुझे दस्तावेज़ कहां मिल सकता है source -d?
डेविड वॉन्ग

9

स्क्रिप्ट का उपयोग करके चलाने के बजाय . run2.sh, आप इसका उपयोग करके चला सकते हैं sh run2.shयाbash run2.sh

एक नया उप-शेल शुरू किया जाएगा, फिर स्क्रिप्ट को चलाने के लिए, यह स्क्रिप्ट के अंत में बंद हो जाएगा, जबकि दूसरा शेल खुला हुआ है।


यदि ऐसा है, तो दूसरा पैरामीटर क्यों sh "." run2.sh?
CHAN

@ H0WARD तुम सही हो मैं डॉट्स निकालना भूल गया। मैंने अब इसका उत्तर संपादित कर दिया है।
वैरिएल मिरिया

1
ओपी स्पष्ट रूप से स्रोत को एक आवश्यकता के रूप में बताता है।
जोनाथन न्यूफेल्ड

3

आप रिटर्न स्टेटमेंट / कमांड के बाद एक अतिरिक्त निकास कमांड जोड़ सकते हैं ताकि यह दोनों के लिए काम करे, कमांड लाइन से स्क्रिप्ट निष्पादित करें और टर्मिनल से सोर्सिंग करें।

स्क्रिप्ट में उदाहरण निकास कोड:

   if [ $# -lt 2 ]; then
     echo "Needs at least two arguments"
     return 1 2>/dev/null
     exit 1
   fi

exitजब आप स्क्रिप्ट का स्रोत बनाते हैं, तो कमांड के साथ लाइन को नहीं बुलाया जाएगाreturn कमांड के ।

जब आप स्क्रिप्ट निष्पादित करते हैं, तो returnकमांड एक त्रुटि देता है। इसलिए, हम त्रुटि संदेश को आगे भेजकर दबा देते हैं /dev/null


3

वास्तव में, मुझे लगता है कि आप किस तरह से भ्रमित हो सकते हैं run a script

यदि आप shस्क्रिप्ट चलाने के लिए उपयोग करते हैं, तो कहें, sh ./run2.shभले ही एम्बेडेड स्क्रिप्ट समाप्त हो जाए exit, आपकी टर्मिनल विंडो अभी भी बनी रहेगी।

हालाँकि, यदि आप उपयोग करते हैं .या source, तो आपकी टर्मिनल विंडो से बाहर आने के साथ-साथ सबस्क्रिप्ट समाप्त हो जाएगा।

अधिक विस्तार के लिए, कृपया देखें कि क्या उपयोग करने shऔर के बीच अंतर है source?


2

यह वैसा ही है जैसे आप अपनी स्क्रिप्ट run2.sh के अंदर एक रन फंक्शन डालते हैं। आप bash tty में अपनी run2.sh फ़ाइल को स्रोत करते समय रन के अंदर एक्ज़िट कोड का उपयोग करें। यदि रन आपकी स्क्रिप्ट से बाहर निकलने के लिए रन फ़ंक्शन को शक्ति देता है और टर्मिनेटर से बाहर निकलने के लिए रन 2.sh को अपनी शक्ति देता है। फिर cuz के रन फंक्शन में आपके टेम्पिनेटर से बाहर निकलने की शक्ति होती है।

    #! /bin/sh
    # use . run2.sh

    run()
    {
        echo "this is run"
        #return 0
        exit 0
    }

    echo "this is begin"
    run
    echo "this is end"

वैसे भी, मैं काज़ के साथ इसे डिजाइन की समस्या मानता हूं।


पाठ से स्पष्ट नहीं है कि यह उत्तर क्या करने का प्रयास करता है, लेकिन यह निश्चित रूप से प्रश्न को हल नहीं करता है।
लुइस डी सूसा

2

मुझे वही समस्या थी और ऊपर के उत्तरों से और जो मुझे समझ में आया कि मेरे लिए आखिरकार क्या काम हुआ:

  1. उदाहरण के लिए, एक शांग लाइन है, जो इच्छित स्क्रिप्ट को आमंत्रित करती है,

    #!/bin/bashbashस्क्रिप्ट निष्पादित करने के लिए उपयोग करता है

मेरे पास दोनों तरह के शेबंग के साथ स्क्रिप्ट हैं। इस वजह से, उपयोग करना shया .विश्वसनीय नहीं था, क्योंकि यह एक गलत निष्पादन की ओर ले जाता है (जैसे कि जब स्क्रिप्ट अपूर्ण हो जाती है)

इसलिए जवाब था, था

    • सुनिश्चित करें कि स्क्रिप्ट में एक शेबंग है, ताकि उसके इच्छित हैंडलर के बारे में कोई संदेह न हो।
    • chmod .sh फ़ाइल है ताकि इसे निष्पादित किया जा सके। (chmod +x file.sh)
    • बिना किसी के सीधे इसे लागू करें shया.

      (./myscript.sh)

आशा है कि यह इसी तरह के प्रश्न या समस्या के साथ किसी को मदद करता है।


1

मुझे लगता है कि ऐसा इसलिए होता है क्योंकि आप इसे डॉट के साथ सोर्स मोड पर चला रहे हैं

. myscript.sh

आपको इसे किसी सबहेल्ड में चलाना चाहिए:

/full/path/to/script/myscript.sh

'स्रोत' http://ss64.com/bash/source.html


अगर . myscript.shकाम करता है तो आपको स्क्रिप्ट के लिए पूर्ण पथ की आवश्यकता नहीं है । अधिक से अधिक, आप की आवश्यकता हो सकती है ./myscript.sh
अल्वारो गोंजालेज

1

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

यहां एक संबंधित टिप है, यदि आप कभी भी एक स्क्रिप्ट चाहते हैं जो सत्र को खुला रखना चाहिए, भले ही यह खट्टा हो या नहीं।

निम्नलिखित उदाहरण को सीधे पसंद किया जा सकता है foo.shया जैसे . foo.sh/ खट्टा किया जा सकता है source foo.sh। किसी भी तरह से यह "बाहर निकलने" के बाद सत्र को खुला रखेगा। $@स्ट्रिंग समारोह बाहरी स्क्रिप्ट के तर्कों की पहुंच न हो तो पारित हो जाता है।

#!/bin/sh
foo(){
    read -p "Would you like to XYZ? (Y/N): " response;
    [ $response != 'y' ] && return 1;
    echo "XYZ complete (args $@).";
    return 0;
    echo "This line will never execute.";
}
foo "$@";

टर्मिनल परिणाम:

$ foo.sh
$ क्या आप XYZ को पसंद करेंगे? (Y / N): n
$। foo.sh
$ क्या आप XYZ को पसंद करेंगे? (Y / N): n
$ |
(टर्मिनल विंडो खुली रहती है और अतिरिक्त इनपुट स्वीकार करती है)

यह मुख्य रूप से exit/ returnजब आप काम करते हैं तो स्क्रैप कोड का एक गुच्छा रखते हुए एक ही टर्मिनल में स्क्रिप्ट परिवर्तनों के परीक्षण के लिए उपयोगी हो सकता है । यह एक अर्थ में कोड को और अधिक पोर्टेबल बना सकता है (यदि आपके पास कई स्क्रिप्ट हैं जो अलग-अलग तरीकों से कॉल की जा सकती हैं या नहीं भी हो सकती हैं), हालांकि यह सिर्फ उपयोग करने के लिए बहुत कम returnऔर exitउपयुक्त कहां है।


0

यदि आपका टर्मिनल एमुलेटर आपके पास नहीं है तो -holdआप एक सॉर्ट की गई स्क्रिप्ट को सैनिटाइज कर सकते हैं और इसके साथ टर्मिनल को पकड़ सकते हैं:

#!/bin/sh
sed "s/exit/return/g" script >/tmp/script
. /tmp/script
read

अन्यथा आप उपयोग कर सकते हैं $TERM -hold -e script


0

साथ ही सुनिश्चित रिटर्न वैल्यू के साथ वापसी सुनिश्चित करें। यदि आप बाहर निकलने का उपयोग करते हैं तो आप एक एग्जिट का सामना करेंगे, यह आपके बेस शेल से बाहर निकल जाएगा क्योंकि स्रोत दूसरी प्रक्रिया (उदाहरण) नहीं बनाता है।


0

एक स्क्रिप्ट है कि या तो एक खोल स्क्रिप्ट के रूप में चलाने के लिए या एक आर सी फ़ाइल के रूप में sourced किया जाना सुरक्षित है लिखने के लिए, स्क्रिप्ट की जाँच करें और तुलना कर सकते हैं $0और $BASH_SOURCEऔर अगर निर्धारितexit सुरक्षित रूप से इस्तेमाल किया जा सकता।

यहाँ उसके लिए एक संक्षिप्त कोड स्निपेट है

[ "X$(basename $0)" = "X$(basename $BASH_SOURCE)" ] && \
    echo "***** executing $name_src as a shell script *****" || \
    echo "..... sourcing $name_src ....."

-1

1) एग्जिट 0 स्क्रिप्ट से बाहर आएगा अगर यह सफल रहा।

2) बाहर निकलें 1 स्क्रिप्ट से बाहर आ जाएगा अगर यह एक विफलता है।

आप उर रीक के आधार पर इन दो से ऊपर की कोशिश कर सकते हैं।

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