बैश कार्यों में वापसी और निकास के बीच अंतर


429

बाहर निकलने के कोड के संबंध में बैश कार्यों में returnऔर exitकथन के बीच क्या अंतर है ?


55
प्रोटिप: help <command>अपने शेल में टाइप करें कि एक शेल बिलिन क्या करेगा, इसके बारे में जानकारी प्राप्त करने के लिए। आपके मामले में help returnऔरhelp exit
सीजएक्स

जवाबों:


318

से man bashपर return [n];

किसी फ़ंक्शन को निष्पादित करने से रोकने के लिए और उसके कॉलर द्वारा n द्वारा निर्दिष्ट मान को वापस करने का कारण बनता है। यदि n को छोड़ दिया गया है, तो वापसी की स्थिति फ़ंक्शन बॉडी में निष्पादित अंतिम कमांड की है।

... पर exit [n]:

शेल को n की स्थिति से बाहर निकलने का कारण बनाएं। यदि n छोड़ दिया गया है, तो निकास स्थिति निष्पादित अंतिम कमांड की है। खोल समाप्त होने से पहले EXIT पर एक जाल निष्पादित किया जाता है।

संपादित करें:

निकास कोड के संबंध में आपके प्रश्न के संपादन के अनुसार, निकास कोड returnसे कोई लेना-देना नहीं है। एक्ज़िट कोड अनुप्रयोगों / लिपियों के लिए अभिप्रेत हैं , फ़ंक्शंस नहीं। तो इस संबंध में, एकमात्र कीवर्ड जो स्क्रिप्ट के निकास कोड को सेट करता है (वह जिसे $?शेल प्रोग्राम का उपयोग करके कॉलिंग प्रोग्राम द्वारा पकड़ा जा सकता है ) exit

संपादित करें 2:

मेरे अंतिम वक्तव्य में exitकुछ टिप्पणियों का उल्लेख किया गया है। अलग करने के लिए बनाया गया था returnऔर exitओ पी की समझ के लिए, और वास्तव में, पर किसी भी एक कार्यक्रम / खोल स्क्रिप्ट का भी बिंदु, exitफोन करने की प्रक्रिया पर एक निकास के कोड के साथ स्क्रिप्ट समाप्त होने का एकमात्र रास्ता है।

हर आदेश खोल में मार डाला एक स्थानीय "बाहर निकलने के कोड" का उत्पादन: यह सेट $?है कि कोड को चर, और साथ इस्तेमाल किया जा सकता if, &&और सशर्त को अन्य ऑपरेटरों अन्य आदेश पर अमल।

ये निकास कोड (और $?चर का मान ) प्रत्येक कमांड निष्पादन द्वारा रीसेट किए जाते हैं।

संयोग से, स्क्रिप्ट द्वारा निष्पादित अंतिम कमांड का निकास कोड स्क्रिप्ट के निकास कोड के रूप में उपयोग किया जाता है, जैसा कि कॉलिंग प्रक्रिया द्वारा देखा जाता है।

अंत में, फ़ंक्शंस, जब बुलाया जाता है, तो शेल कोड्स के रूप में कार्य करता है जो कोड से बाहर निकलने के संबंध में है। फ़ंक्शन का निकास कोड (फ़ंक्शन के भीतर ) का उपयोग करके सेट किया गया है return। इसलिए जब किसी फ़ंक्शन return 0को चलाया जाता है, तो फ़ंक्शन एक्ज़ीक्यूशन समाप्त हो जाता है, जिससे 0 का एग्ज़िट कोड दिया जाता है।


10
बिल्कुल नहीं। यह हमेशा वर्तमान शेल से एक मान लौटाता है। इससे कोई फर्क नहीं पड़ता कि आप किसी फंक्शन के अंदर हैं या नहीं।
डिएगो सेविला

10
अपने संपादन पर टिप्पणी करें: मैं रिटर्न वैल्यूज़ और एक्ज़िट कोड्स को भ्रमित कर सकता हूं, लेकिन func(){ return 50; };func;echo $?ईकोस 50। इसलिए $?शेल वेरिएबल को सीमित नहीं किया जाना चाहिए exit
lecodesportif

8
" $?सबसे हाल ही में निष्पादित अग्रभूमि पाइपलाइन की निकास स्थिति का विस्तार करता है।" वह निकास शेल से कॉल के रूप में हो सकता है exit(या स्क्रिप्ट के अंत को मारना) या returnफ़ंक्शन के भीतर कॉल के रूप में हो सकता है ।
घेराबंदी

11
@lecodesportif: इस स्क्रिप्ट द्वारा निष्पादित अंतिम कमांड के परिणाम $? के लिए वर्तमान प्रक्रिया / स्क्रिप्टexit या तो तक सीमित है । तो, यदि आपकी अंतिम स्क्रिप्ट लाइन उस फ़ंक्शन को कॉल करती है, और वह फ़ंक्शन 50 देता है, हाँ, तो $?आप उस प्रक्रिया का उत्पादन करते हैं जिसे आप 50 कहते हैं । हालांकि, इसका कोई मतलब नहीं है return, क्योंकि यह है वर्तमान स्क्रिप्ट तक ही सीमित है। यह तभी होता है जब यह फ़ंक्शन कॉल स्क्रिप्ट का अंतिम वाक्य होता है। exitहालाँकि, हमेशा स्क्रिप्ट को पूरा करते हैं और $? कॉलिंग प्रक्रिया के अनुसार उस मान को वापस करते हैं ।
डिएगो सेविला

11
-1 लाइन से मुझे भ्रमित returnकरने के लिए "एक्जिट कोड से कोई लेना देना नहीं है।" प्रयोग मुझे बताता है कि किसी फ़ंक्शन के रिटर्न कोड और स्क्रिप्ट के निकास कोड के बीच कोई कार्यात्मक अंतर नहीं है।
जैक

296

returnवर्तमान फ़ंक्शन को कार्यक्षेत्र से बाहर जाने exitका कारण बना देगा , जबकि स्क्रिप्ट को उस बिंदु पर समाप्त होने का कारण होगा जहां इसे कहा जाता है। यह समझाने के लिए एक नमूना कार्यक्रम यहां दिया गया है:

#!/bin/bash

retfunc()
{
    echo "this is retfunc()"
    return 1
}

exitfunc()
{
    echo "this is exitfunc()"
    exit 1
}

retfunc
echo "We are still here"
exitfunc
echo "We will never see this"

उत्पादन

$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()

17
अच्छा उदाहरण है। आप 1 में बाहर निकलने का मूल्य भी दिखा सकते हैं $?
डिएगो सेविला

48
ध्यान दें कि यह फ़ंक्शन "हम अभी भी यहाँ हैं" प्रिंट नहीं करेंगे यदि आप "रेटफंच" के लिए कॉल से पहले "सेट-ई" जोड़ते हैं।
माइकल

4
हालांकि, echo fnord | while read x; do exitfunc; done; echo "still here""अभी भी यहां" प्रिंट होगा। ऐसा लगता है कि whileइस परिदृश्य में केवल उप-शेल से बाहर है।
ट्रिपल डी

अनुमानित वर्कअराउंड है, done || exit $?लेकिन यह बदसूरत है और ठीक समकक्ष नहीं है।
ट्रिपल डि

2
+1 यह जोड़ने के लिए उपयोगी हो सकता है: `` ` returnवर्तमान फ़ंक्शन या स्रोत से बाहर जाने के लिए स्क्रिप्ट के कारण होगा ।
इसहाक

56

मुझे नहीं लगता कि किसी ने वास्तव में पूरी तरह से सवाल का जवाब दिया है क्योंकि वे यह नहीं बताते हैं कि दोनों का उपयोग कैसे किया जाता है। ठीक है, मुझे लगता है कि हम जानते हैं कि निकास स्क्रिप्ट को मारता है, जहां कभी भी इसे कहा जाता है और आप इसे एक स्थिति दे सकते हैं जैसे कि बाहर निकलें या बाहर निकलें 0 या बाहर निकलें 7 और इसके बाद। इसका उपयोग यह निर्धारित करने के लिए किया जा सकता है कि स्क्रिप्ट को किसी अन्य स्क्रिप्ट आदि से बाहर निकलने के लिए मजबूर करने के लिए मजबूर किया गया था।

जब कॉल किया जाता है, तो फ़ंक्शन के व्यवहार को इंगित करने के लिए निर्दिष्ट मान लौटाएगा, आमतौर पर 1 या 0. उदाहरण के लिए:

    #!/bin/bash
    isdirectory() {
      if [ -d "$1" ]
      then
        return 0
      else
        return 1
      fi
    echo "you will not see anything after the return like this text"
    }

इस तरह की जाँच करें:

    if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi

या इस तरह:

    isdirectory || echo "not a directory"

इस उदाहरण में, परीक्षण का उपयोग यह इंगित करने के लिए किया जा सकता है कि क्या निर्देशिका मिली थी। ध्यान दें कि वापसी के बाद कुछ भी फ़ंक्शन में निष्पादित नहीं किया जाएगा। 0 सही है, लेकिन गलत है शेल में 1 है, जो अन्य ठेला लंग्स से अलग है।

कार्यों के बारे में अधिक जानकारी के लिए: http://www.linuxjournal.com/content/return-values-bash-functions

नोट: isdirectory फ़ंक्शन केवल अनुदेशात्मक उद्देश्यों के लिए है। यह नहीं होना चाहिए कि आप एक वास्तविक स्क्रिप्ट में इस तरह के विकल्प का प्रदर्शन कैसे करते हैं।


3
या बस test -d $1उसी परिणाम को प्राप्त करने के लिए उपयोग करें। कभी नहीं if <check> return else return<check>अकेले सभी भाषाओं में वही काम करेंगे जो मैं कम से कम जानता हूं।
एरिकबवर्क

4
इरिक क्या कह रहा है, इसके बारे में और भी स्पष्ट होना isdirectory() { [ -d "$1" ]; }: आपके यहाँ जैसा है वैसा ही व्यवहार करेंगे: शेल फ़ंक्शन का डिफ़ॉल्ट रिटर्न मान, चाहे वह कोड के अंत तक पहुँच जाए या returnबिना किसी तर्क के, क्या वह है सबसे हाल की कमान।
चार्ल्स डफी

11
यहां अन्य टिप्पणीकार माइक क्यू के उदाहरण की शैली की आलोचना कर रहे हैं, जब वास्तव में वह returnबयान के व्यवहार के बारे में बात कर रहे हैं । यह सच है कि उसका उदाहरण सरल है और उत्पादन में उपयोग नहीं किया जाना है। लेकिन यह आसान है, इसलिए यह उसके काम को ठीक करता है। इसमें कुछ भी गलत नहीं है।
माइक एस

धन्यवाद माइक एस, हाँ, मैं मानता हूं कि सबसे सरल उदाहरण सबसे अच्छा है कि बाहर निकलें बनाम वापसी। अन्य टिप्पणी निश्चित रूप से मान्य हैं, और अधिक उन्नत बैश कोडर के लिए ;-) विचार किया जाना चाहिए
माइक क्यू

1
कुछ लोग यह कह सकते हैं कि यह वास्तव में प्रश्न से संबंधित नहीं है, लेकिन इससे संबंधित समस्या का उत्तर दिया और मुझे इस प्रश्न का पता लगाने के लिए प्रेरित किया। :-)
जेसी स्टील

33

याद रखें, फ़ंक्शंस एक स्क्रिप्ट के लिए आंतरिक होते हैं और सामान्य रूप से वे वापसी से आते हैं जिन्हें वे रिटर्न स्टेटमेंट का उपयोग करके कहते थे। बाहरी स्क्रिप्ट को कॉल करना पूरी तरह से एक और मामला है, और स्क्रिप्ट आमतौर पर एक एक्जिट स्टेटमेंट के साथ समाप्त होती है।

"BASH कार्यों में रिटर्न और एग्जिट स्टेटमेंट के बीच का अंतर कोड से बाहर निकलने के संबंध में" बहुत कम है। दोनों एक स्थिति लौटाते हैं, प्रति से मान नहीं । शून्य की स्थिति सफलता को इंगित करती है, जबकि किसी भी अन्य स्थिति (1 से 255) में विफलता का संकेत मिलता है। वापसी विवरण उस स्क्रिप्ट पर वापस आ जाएगा जहां से इसे बुलाया गया था, जबकि बाहर निकलने का बयान पूरी स्क्रिप्ट को समाप्त कर देगा जहां से यह सामना किया गया है।

return 0  # returns to where the function was called.  $? contains 0 (success).

return 1  # returns to where the function was called.  $? contains 1 (failure).

exit 0  # exits the script completely.  $? contains 0 (success).

exit 1  # exits the script completely.  $? contains 1 (failure).

यदि आपका फ़ंक्शन बस बिना किसी विवरण के समाप्त होता है, तो निष्पादित अंतिम कमांड की स्थिति स्थिति कोड के रूप में वापस आ जाती है (और इसे रखा जाएगा $?)।

याद रखें, वापस लौटना और बाहर निकलना 0 से 255 तक का स्टेटस कोड वापस मिलता है $?। आप स्थिति कोड में कुछ और नहीं भर सकते (उदाहरण के लिए "कैट"); यह काम नहीं करेगा। लेकिन, एक स्क्रिप्ट स्थिति कोड का उपयोग करके विफलता के लिए 255 अलग-अलग कारणों को वापस कर सकती है।

आप कॉलिंग स्क्रिप्ट में निहित चर सेट कर सकते हैं, या फ़ंक्शन में गूंज परिणाम कर सकते हैं और कॉलिंग स्क्रिप्ट में कमांड प्रतिस्थापन का उपयोग कर सकते हैं; लेकिन वापसी और बाहर निकलने का उद्देश्य स्थिति कोड पारित करना है, न कि मान या गणना परिणाम, क्योंकि कोई सी जैसी प्रोग्रामिंग भाषा में उम्मीद कर सकता है।


25

कभी-कभी, आप स्क्रिप्ट का उपयोग करके चलाते हैं .या source

. a.sh

आप एक शामिल हैं exitमें a.sh, यह सिर्फ स्क्रिप्ट समाप्त नहीं होगा, लेकिन अपने खोल सत्र को समाप्त।

यदि आप एक में शामिल हैं returnमें a.sh, यह बस स्क्रिप्ट प्रसंस्करण बंद हो जाता है।


1
लेकिन जब मैं सिर्फ a.sh चलाता हूं तो मुझे एक त्रुटि मिलती है return: can only 'return' from a function or sourced script, जो इसे सामान्य स्क्रिप्ट के लिए अनुपयुक्त बना देती है।
पीटर - मोनिका

एक स्क्रिप्ट में शीर्ष स्तर पर, न तो allस्थितियों में उपयुक्त है। वर्तमान शेल में स्क्रिप्ट का उपयोग करना .या sourceचलाना, इसके बजाय उप-शेल खोलना। स्क्रिप्ट को यह जानना है कि इसका उपयोग कैसे किया जाना है। इसके विपरीत करने वाले उपयोगकर्ता के लिए शोक। व्यक्तिगत रूप से, मैं उन्हें पहली बार चलाने से पहले स्क्रिप्ट पढ़ने की सलाह देता हूं।
जेसी चिशोल्म

3
मेरे पास आया एक भयानक ट्रिक एक trapफ़ंक्शन का उपयोग करने के लिए है ERR EXITऔर फिर पहले एक असफल कमांड के एग्ज़िट कोड को सेव करें errCode=$?और फिर स्क्रिप्ट से बाहर निकलें (खट्टा है या नहीं) return $errCode || exit $errCodeजहां से ||मतलब है "अगर मैं वापस नहीं आ सकता क्योंकि मैं खट्टा नहीं था , इसके बजाय बाहर निकलें ”।
ड्रैगन 88

6

सरल शब्दों में (मुख्य रूप से कोडिंग में नौसिखिया के लिए), हम कह सकते हैं,

`return` : exits the function,
`exit()` : exits the program(called as process while running)

इसके अलावा, अगर आपने देखा, तो यह बहुत बुनियादी है लेकिन ...,

`return` : is the keyword
`exit()` : is the function

1
एक बैश स्क्रिप्ट में, exitइससे अधिक या कम फ़ंक्शन नहीं है return। वे अंतर्निहित कमांड हैं। वे आरक्षित शब्द भी नहीं हैं।
पीटर - मोनिका को बहाल करें

6
  • exit वर्तमान को समाप्त करें प्रक्रिया को ; एक्ज़िट कोड के साथ या उसके बिना, एक प्रोग्राम फ़ंक्शन से अधिक इस प्रणाली पर विचार करें। ध्यान दें कि सोर्सिंग करते समय, exitशेल समाप्त हो जाएगा, हालांकि, जब रनिंग सिर्फ exitस्क्रिप्ट होगी ।

  • returnएक फ़ंक्शन से, कॉल के बाद या रिटर्न कोड के बिना निर्देश पर वापस जाएं। returnवैकल्पिक है और यह फ़ंक्शन के अंत में निहित है। returnकेवल एक फ़ंक्शन के अंदर उपयोग किया जा सकता है।

मैं यह जोड़ना चाहता हूं कि खट्टा होने के दौरान, exitशेल को मारे बिना किसी फ़ंक्शन के भीतर से स्क्रिप्ट करना आसान नहीं है । मुझे लगता है, एक उदाहरण 'परीक्षण' स्क्रिप्ट पर बेहतर है

#!/bin/bash
function die(){
   echo ${1:=Something terrible wrong happen}
   #... clean your trash
   exit 1
}

[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"

निम्नलिखित कार्य कर रहा है:

user$ ./test
Whatever is not available
user$

test -और- खोलना बंद हो जाएगा।

user$ . ./test
Whatever is not available

केवल testखत्म हो जाएगा और संकेत दिखाएगा।

समाधान में (और संभावित प्रक्रिया को संलग्न करना है)

#!/bin/bash
function die(){
   echo $(1:=Something terrible wrong happen)
   #... clean your trash
   exit 1
}

( # added        
    [ -f /whatever/ ] || die "whatever is not available"
    # now we can proceed
    echo "continue"
) # added

अब, दोनों मामलों में केवल testबाहर निकल जाएगा।


को जोड़ने (और )उस ब्लॉक को एक उप-शेल में डालता है, प्रभावी रूप से अन- .सोर्स (स्रोत) कमांड करता है जैसे कि आपने टेस्ट स्क्रिप्ट को सामान्य रूप से चलाया था, जो कि एक सब-शेल में है। IOf स्क्रिप्ट के साथ नहीं चलती है .या sourceफिर आपके पास प्रभावी रूप से 2 उप-गोले हैं।
जेसी चिशोल्म

3

ओपी का प्रश्न: कोड से बाहर निकलने के संबंध में BASH के रिटर्न और एग्जिट स्टेटमेंट में क्या अंतर है?

Firtly, कुछ स्पष्टीकरण आवश्यक है:

  • ए (फ़ंक्शन | शेल) के निष्पादन को समाप्त करने के लिए ए (वापसी | निकास) बयान की आवश्यकता नहीं है। A (फ़ंक्शन | शेल) तब समाप्त होगा जब यह अपनी कोड सूची के अंत तक पहुँच जाता है, यहां तक ​​कि बिना (रिटर्न | एक्जिट) स्टेटमेंट के भी।
  • समाप्त (फ़ंक्शन | शेल) से मान वापस करने के लिए A (वापसी | निकास) कथन की आवश्यकता नहीं है। हर प्रक्रिया में एक अंतर्निहित चर $ है? जिसका हमेशा एक संख्यात्मक मान होता है। यह एक विशेष चर है जिसे "=? 1" की तरह सेट नहीं किया जा सकता है, लेकिन केवल विशेष तरीकों (नीचे देखें *) में सेट किया गया है। $ का मूल्य? अंतिम कमांड (जिसे फ़ंक्शन कहा जाता है। सब शेल) में निष्पादित होने के बाद, वह मान है जिसे (फ़ंक्शन कॉलर | पैरेंट शेल) पर वापस भेजा जाता है। यह सही है कि क्या अंतिम कमांड निष्पादित की गई है ("वापसी [एन]" | "बाहर निकलें [एन]") या सादा ("वापसी" या कुछ और जो अंतिम फ़ंक्शन कोड में अंतिम कमांड होता है)।

उपरोक्त बुलेट सूची में, "x (y | y)" से चुनें या तो हमेशा पहला आइटम या हमेशा दूसरा आइटम फ़ंक्शंस के बारे में स्टेटमेंट प्राप्त करने के लिए या शेल या क्रमशः बाहर निकलें।

क्या स्पष्ट है कि वे दोनों विशेष चर $ का सामान्य उपयोग साझा करते हैं? मान समाप्त करने के बाद वे ऊपर की ओर जाने के लिए।

* अब विशेष तरीकों के लिए कि $? जम सकता है:

  • जब कोई फ़ंक्शन समाप्त हो जाता है और कॉल करने वाला वापस लौटता है तो $? कॉलर में $ के अंतिम मूल्य के बराबर होगा? समाप्त समारोह में।
  • जब कोई माता-पिता खोल या स्पष्ट रूप से एक उप शेल पर प्रतीक्षा करता है और उस उप शेल को समाप्त करके जारी किया जाता है, तो $? मूल खोल में $ के अंतिम मूल्य के बराबर होगा? समाप्त उप शेल में।
  • कुछ अंतर्निहित फ़ंक्शन $ को संशोधित कर सकते हैं? उनके परिणाम पर निर्भर करता है। लेकिन कुछ नहीं।
  • अंतर्निहित कार्यों "वापसी" और "निकास", जब दोनों $ एक संख्यात्मक तर्क के बाद? तर्क के साथ, और निष्पादन को समाप्त करें।

यह ध्यान देने योग्य है कि $? इस तरह से एक उप खोल में निकास कॉल करके एक मान सौंपा जा सकता है:

# (exit 259)
# echo $?
3  

4
मामले में कुछ नहीं देख पाए, exit 259के रूप में इको 3क्योंकि अंतिम बाहर निकलें मूल्य एक एकल बाइट है। 259 % 256 = 3
जेसी चिशोल्म

0

सबसे पहले, returnएक कीवर्ड है और exitमेरा दोस्त एक फ़ंक्शन है।

उस ने कहा, यहाँ स्पष्टीकरण का एक सरल है।

return यह एक फ़ंक्शन से एक मान लौटाता है।

exit यह बाहर निकलता है या चालू शेल को छोड़ देता है।


ज़रुरी नहीं! आप तार्किक रूप से गलत हैं। returnएक कीवर्ड है, जबकि बाहर निकलें एक फ़ंक्शन है। रिटर्न सिर्फ बाहर निकलने के कोड से बहुत अधिक है, यही वजह है कि तुलना उचित नहीं है।
अहमद आवा

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

4
न तो exitहै और न ही return"कीवर्ड", या, बैश मैनुअल कॉल उन्हें, "सुरक्षित शब्द" के रूप में कर रहे हैं। बैश फ़ंक्शन के अर्थ में न तो कोई "फ़ंक्शन" है, न ही। दोनों बेस कमांडो हैं , बैश लिंगो में। (वहाँ है एक सी मानक पुस्तकालय बुलाया समारोह exit(), और सी प्रोग्रामिंग भाषा एक आरक्षित शब्द है return, लेकिन उन बैश आदेशों के साथ भ्रमित नहीं होना चाहिए, भले ही उनके अर्थ विज्ञान दिलचस्प समान हैं।)
पीटर - को पुनः स्थापित मोनिका
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.