लिनक्स में निकास कोड के न्यूनतम और अधिकतम मान क्या हैं?


40

लिनक्स में निम्नलिखित निकास कोड का न्यूनतम और अधिकतम मान क्या है:

  1. बाहर निकलने का कोड एक द्विआधारी निष्पादन योग्य (उदाहरण के लिए: C प्रोग्राम) से लौटा है।
  2. बाहर निकलने का कोड एक बैश स्क्रिप्ट (कॉल करते समय exit) से वापस आ गया ।
  3. निकास कोड एक फ़ंक्शन (जब कॉलिंग return) से लौटा । मुझे लगता है कि यह 0और के बीच है 255

भाग 3 के लिए, क्या आपका मतलब शेल फ़ंक्शन से लौट रहा है ? यही कारण है कि खोल पर निर्भर हो सकता है, लेकिन मैं ध्यान दें कि बैश मैनुअल कहते हैं, " बाहर निकलें स्थितियों के बीच गिर 0 और 255 और" " खोल builtins और मिश्रित आदेशों से बाहर निकलें स्थितियां भी इस सीमा तक सीमित हैं। " returnनिश्चित रूप से है, एक खोल builtin।
टॉबी स्पाइट

संबंधित (आपके अधिकांश प्रश्नों के उत्तर हैं): प्रक्रिया समाप्त होने पर डिफ़ॉल्ट निकास कोड?
स्टीफन चेज़ेलस

@ टॉबीस्पाइट, यह bashशेल की एक सीमा है । जैसे कुछ अन्य गोले zshकिसी भी हस्ताक्षरित 32 बिट मान को वापस कर सकते हैं exit। कुछ की तरह rcया esप्रकार वे समर्थन करते हैं (अदिश या सूची) में से किसी का लौट सकते हैं डेटा। विवरण के लिए लिंक किए गए प्रश्नोत्तर देखें।
स्टीफन चेजलस

जवाबों:


74

_exit()/ exit_group()सिस्टम कॉल के लिए दी गई संख्या (कभी-कभी बाहर निकलने की स्थिति के साथ अस्पष्टता से बचने के लिए निकास कोड के रूप में संदर्भित किया जाता है जो निकास कोड या संकेत संख्या और अतिरिक्त जानकारी के एन्कोडिंग की भी बात करता है जो इस प्रक्रिया पर निर्भर करता है कि क्या सामान्य रूप से मारा गया था या बाहर निकल गया था। ) प्रकार है int, इसलिए लिनक्स जैसे यूनिक्स जैसी प्रणालियों पर, आमतौर पर एक 32bit पूर्णांक -2147483648 (-2 31 ) से 2147483647 (2 31 -1) के मूल्यों के साथ होता है ।

हालांकि, सभी सिस्टम पर, जब माता-पिता की प्रक्रिया (या बच्चे subreaper या initअगर माता-पिता की मृत्यु हो गई) का उपयोग करता है wait(), waitpid(), wait3(), wait4()सिस्टम कॉल इसे पुनः प्राप्त करने के लिए, केवल इसके बारे में कम 8 बिट उपलब्ध (मान 0 255 (2 करने के लिए कर रहे हैं 8 - 1))।

waitid()अधिकांश प्रणालियों पर एपीआई (या सिगल्डएलडी पर एक सिग्नल हैंडलर) का उपयोग करते समय , (और पोसिक्स के रूप में अब मानक के 2016 संस्करण में अधिक स्पष्ट रूप से आवश्यक है ( _exit()विनिर्देश देखें )), पूर्ण संख्या उपलब्ध है ( si_statusलौटे संरचना के क्षेत्र में) )। यह लिनक्स पर अभी तक ऐसा नहीं है, जो कि waitid()एपीआई के साथ संख्या को 8 बिट तक कम कर देता है, हालांकि भविष्य में इसके बदलने की संभावना है।

आम तौर पर, आप केवल मान 0 (आमतौर पर सफलता का अर्थ) का उपयोग केवल 125 तक करना चाहते हैं, क्योंकि कई गोले निकास स्थिति के अपने $?प्रतिनिधित्व में 128 से ऊपर के मूल्यों का उपयोग करते हैं, जो कि मारे जाने की प्रक्रिया की संकेत संख्या को सांकेतिक शब्दों में बदलना है और विशेष के लिए 126 और 127 है। शर्तेँ।

आप 126 का उपयोग करने के लिए 255 का उपयोग करना चाह सकते हैं exit(), जैसा कि वे शेल के लिए करते हैं $?(जैसे जब कोई स्क्रिप्ट करता है ret=$?; ...; exit "$ret")। 0 -> 255 के बाहर मूल्यों का उपयोग करना आमतौर पर उपयोगी नहीं होता है। आप आमतौर पर केवल यही करते हैं कि यदि आप जानते हैं कि माता-पिता waitid()एपीआई सिस्टम का उपयोग करेंगे जो कम नहीं करते हैं और आपको 32 बिट श्रेणी के मानों की आवश्यकता होती है। ध्यान दें कि यदि आप एक exit(2048)उदाहरण के लिए करते हैं, तो पारंपरिक wait*()API का उपयोग करके माता-पिता द्वारा सफलता के रूप में देखा जाएगा ।

अधिक जानकारी पर:

उस प्रश्नोत्तर को आपके अधिकांश अन्य प्रश्नों का उत्तर देना चाहिए और स्पष्ट करना चाहिए कि बाहर निकलने की स्थिति से क्या मतलब है । मैं कुछ और चीजें जोड़ूंगा:

एक प्रक्रिया तब तक समाप्त नहीं हो सकती जब तक कि उसे मार नहीं दिया जाता _exit()/ exit_group()कॉल / सिस्टम कॉल नहीं करता। आप से लौटने जब main()में C, libc कॉल कि वापसी मान के साथ सिस्टम कॉल।

अधिकांश भाषाओं में एक exit()फ़ंक्शन होता है जो उस सिस्टम कॉल को लपेटता है, और वे जो मूल्य लेते हैं, यदि कोई आम तौर पर सिस्टम कॉल के रूप में पारित हो जाता है। (ध्यान दें कि आम तौर पर वे सी- exit()फंक्शन द्वारा किए गए क्लीन-अप की तरह अधिक काम करते हैं जो स्टीडियो बफ़र्स को फ्लश करता है, atexit()हुक चलाता है ...)

कम से कम यह मामला है:

$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234)                        = ?
$ strace -e exit_group perl -e 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234)                        = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234)                        = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)

आप कभी-कभी कुछ देखते हैं जो 0-255 के बाहर मूल्य का उपयोग करते समय शिकायत करते हैं:

$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1)                           = ?

जब आप नकारात्मक मान का उपयोग करते हैं तो कुछ गोले शिकायत करते हैं:

$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2)                           = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: `-1234' is not a valid integer
exit_group(2)                           = ?

POSIX अपरिभाषित व्यवहार को छोड़ देता है यदि exitविशेष बिलिन में पारित मूल्य 0-> 255 के बाहर है।

कुछ गोले कुछ अप्रत्याशित व्यवहार दिखाते हैं यदि आप करते हैं:

  • bash(और mkshलेकिन pdkshयह जिस पर आधारित नहीं है) अपने आप को 8 बिट्स के मान को छोटा करने के लिए लेता है:

    $ strace -e exit_group bash -c 'exit 1234'
    exit_group(210)                         = ?
    

    तो उन गोले में, यदि आप 0-255 के बाहर मूल्य के साथ बाहर निकलना चाहते हैं, तो आपको कुछ ऐसा करना होगा:

    exec zsh -c 'exit -- -12345'
    exec perl -e 'exit(-12345)'
    

    यह उसी प्रक्रिया में एक और कमांड निष्पादित करता है जो सिस्टम कॉल को आपके इच्छित मान के साथ कॉल कर सकता है

  • जैसा कि अन्य प्रश्नोत्तर में उल्लेख किया गया है, ksh93257 से 256 + max_signal_number से बाहर निकलने के मूल्यों के लिए सबसे अजीब व्यवहार है जहां कॉल करने के बजाय exit_group(), यह खुद को संबंधित सिग्नल¹ से मारता है।

    $ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    zsh: suspended (signal)  ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    

    और अन्यथा bash/ जैसी संख्या को काट देता है mksh


Change हालांकि अगले संस्करण में बदलने की संभावना है। अब जब ksh93एटी एंड टी के बाहर सामुदायिक प्रयास के रूप में विकास को ले लिया गया है, तो उस व्यवहार को, भले ही पोसिक्स द्वारा किसी तरह प्रोत्साहित किया गया हो, वापस लाया जा रहा है।


2
क्या आपको पता है कि si_statusलिनक्स के लिए पूर्ण निकास कोड लागू करने पर कोई चर्चा है ?
रुस्लान

2
@Ruslan, austingroupbugs.net/view.php?id=594#c1318 (एरिक ब्लेक ( रेडहैट )) द्वारा दिए गए लिंक पर मैंने जो लिंक दिया , उससे ज्यादा नहीं
स्टीफन चेजालस

1
"एक प्रकार का इंट है, इसलिए एक 32 बिट पूर्णांक"। लिनक्स वास्तव में गारंटी देता है कि एक इंट हमेशा 32 बिट होगा? यहां तक ​​कि जब उन छोटे माइक्रोकंट्रोलर में से कुछ पर चल रहा है? यह मुझे बहुत अजीब लगता है। POSIX निश्चित रूप से नहीं करता है।
वू

@Voo, उन छोटे माइक्रोकंट्रोलर लिनक्स नहीं चला सकते। जबकि C को intकम से कम 16 बिट्स की आवश्यकता होती है , लेकिन POSIX को कम से कम 32 बिट्स और प्रोग्रामिंग वातावरण के लिए uint32_t होना आवश्यक है । मुझे नहीं पता कि लिनक्स किसी भी प्रोग्रामिंग वातावरण का समर्थन करता है, जहां कुछ भी 32 बिट्स हैं, लेकिन मैं कभी भी किसी भी जगह नहीं आया हूं।
स्टीफन चेजालस

1
POSIX comliant OS पर, आपको बॉर्न शेल के हाल के संस्करण में पूर्ण 32 बिट एक्ज़िट कोड मिल सकता है, देखें: schillix.sourceforge.net/man/man1/bosh.1.html
schily

12

न्यूनतम है 0, और इसे सफलता मूल्य माना जाता है। अन्य सभी विफलताएं हैं। अधिकतम के रूप में 255भी जाना जाता है -1

ये नियम स्क्रिप्ट और अन्य निष्पादन योग्य, साथ ही शेल फ़ंक्शन दोनों के लिए लागू होते हैं।

बड़ा मान 256 modulo का परिणाम है।


2
सटीक होने के लिए, कुछ बॉर्न-जैसे गोले (लेकिन नहीं bashया अन्य आमतौर पर उपयोग किए जाने वाले अन्य) में exitनिर्मित बिलिन के लिए पारित निकास कोड को modulo-256 के रूप में नहीं माना जाता है, और इसके बजाय एक त्रुटि का कारण बनता है। (उदाहरण के लिए, आम exit -1वास्तव exit 255में अधिकांश गोले में एक पोर्टेबल समकक्ष नहीं है )। और क्या exit(-1)सी स्तर के बराबर exit(255)है एक विस्तार है जो काम करने के लिए निश्चित है, लेकिन कार्यान्वयन परिभाषित व्यवहार पर निर्भर करता है (हालांकि यह आधुनिक प्रणालियों पर कोई समस्या नहीं है जो आप व्यवहार में उपयोग करने की संभावना रखते हैं)।
मत्तीसुर

मैं जो जानता हूं, उससे ksh93 exit(1)पैरामीटर को 8 बिट तक सीमित करता है ।
शास्त्री

6

यह बहुत आसान लग रहा है, लेकिन ओह तेह व्यर्थ है।

C भाषा (जो कि प्रत्यक्ष या अप्रत्यक्ष रूप से अधिकांश अन्य भाषाओं का अनुसरण करती है) के लिए आवश्यक है कि रिटर्न के मूल्य के समान तर्क के साथ mainकॉलिंग के बराबर से exitलौटे। यह एक पूर्णांक (वापसी प्रकार बहुत स्पष्ट रूप से है int), इसलिए सिद्धांत रूप में सीमा होगा INT_MINकरने के लिए INT_MAX

हालाँकि, पोसिक्स कहता है कि केवल लोअरस्टोस्ट 8 बिट्स exitको एक प्रतीक्षा मूल प्रक्रिया के लिए उपलब्ध कराया जाएगा, जिसका शाब्दिक अर्थ "स्थिति और 0xFF" था
तो, व्यवहार में, निकास कोड एक (अभी भी हस्ताक्षरित) पूर्णांक है जिसमें केवल सबसे कम 8 बिट सेट हैं।

इस प्रकार न्यूनतम -128 होगा, और अधिकतम 127 होगा । रुको, यह सच नहीं है। यह 0 से 255 होगा।

लेकिन अफसोस, बेशक यह इतना आसान नहीं हो सकता । व्यवहार में, लिनक्स (या बल्कि बैश) इसे अलग तरीके से करता है । रिटर्न कोड की वैध सीमा 0 से 255 (यानी अहस्ताक्षरित) है।

भ्रम से बचने के मामले में सुरक्षित पक्ष पर रहने के लिए, यह शायद एक अच्छा विचार है कि केवल यह मान लें कि रिटर्न कोड अहस्ताक्षरित हैं, और जो कुछ भी आपको वापस मिलता है waitउसे अहस्ताक्षरित कर दें। इस तरह यह एक शेल में जो आप देखते हैं, उसके अनुरूप है। चूंकि सबसे ऊपरी बिट्स (सबसे महत्वपूर्ण एक सहित) को हटा दिया जाता है, इसलिए यह "गलत" भी नहीं है क्योंकि तकनीकी रूप से हस्ताक्षरित होने के बावजूद, वास्तविक मान हमेशा अहस्ताक्षरित होते हैं (क्योंकि साइन बिट कभी सेट नहीं होता है)।
यह एक एक्जिट कोड की तुलना करने की सामान्य त्रुटि से बचने में भी मदद करता है -1, जो किसी अजीब कारण से कभी भी प्रकट नहीं होता है जब कोई प्रोग्राम बाहर निकलता है -1(अच्छी तरह से, क्यों लगता है!)।

अपने अंतिम बिंदु के बारे में, किसी फ़ंक्शन से लौट रहा है, यदि यह फ़ंक्शन होता है main, तो ऊपर देखें। अन्यथा, यह निर्भर करता है कि फ़ंक्शन का रिटर्न प्रकार क्या है, यह सिद्धांत रूप में कुछ भी हो सकता है (सहित void)।


१ ९ 1989 ९ से पहले जब आप waitid()पेश किए गए थे, तब आप सही थे ।
शास्त्री

@ शिल्पी: निश्चित नहीं कि तुम्हारा क्या मतलब है? waitid()बस एक ही काम करता है, थोड़ा अलग तरीके से। यह एक विशेष आईडी या किसी थ्रेड के लिए इंतजार कर रहा है, और यह उठाई करने के लिए परिणामों लिखते siginfo_tसंरचना जहां si_statusहै int(ताकि ... पर हस्ताक्षर किए , सिर्फ एक ही)। फिर भी, exit()केवल लोअरमेस्ट 8 बिट्स पास करता है, इसलिए ... हुड के नीचे बिल्कुल वही।
डेमोन

exit()पैरामीटर के सभी 32 बिट्स को कर्नेल में पास करता है और waitid()सभी 32 बिट्स को बाहर निकलने के कोड से वापस करता है। हो सकता है कि आपने लिनक्स पर जाँच की हो जहाँ बग्स को ठीक करने की किसी को परवाह नहीं है। यदि आप मेरी बात पर विश्वास नहीं करते हैं, तो इसे POSIX
कंप्लीट

@ शिल्पी: अगर यह सच है (मुझे नहीं लगता कि यह है, लेकिन वैसे भी), तो लिनक्स टूट गया हैexitविशेष रूप से "विवरण" के तहत दूसरी पंक्ति के लिंक-टू-इन-जवाब POSIX विनिर्देश को पढ़ें, जिसमें कहा गया है: "हालांकि केवल कम से कम महत्वपूर्ण 8 बिट्स (यानी, स्थिति और 0377) एक प्रतीक्षा मूल प्रक्रिया के लिए उपलब्ध होंगे ” । यह है कि एक अनुरूप कार्यान्वयन कैसे काम करता है - सबसे कम 8 बिट्स, 32 नहीं। क्या आपके पास 32 बिट्स के लिए एक संदर्भ है?
डेमोन

मुझे लगा कि मैंने उल्लेख किया है कि लिनक्स टूट गया है। इससे भी बदतर: लिनक्स कर्नेल लोग बग को ठीक करने से इनकार करते हैं। यदि आप POSIX मानक को पढ़ते हैं, तो आप पाएंगे कि 1995 संस्करण (SUSv1) मूल रूप से 1989 में SVr4 द्वारा शुरू की गई विशेषता की व्याख्या करता है waitid()और मानक के हाल के संस्करणों (जैसे SUSv7tc2) ने भी स्पष्ट रूप से समझाया और हैंडलर वापसी के siginfo_tलिए पारित संरचना। पैरामीटर SIGCHLDसे सभी 32 बिट्स exit()
10

2
  1. बाहर निकलने का कोड एक द्विआधारी निष्पादन योग्य (उदाहरण के लिए: C प्रोग्राम) से लौटा है।
  2. एग्जिट कोड बैश स्क्रिप्ट (एक्जिट कॉलिंग के समय) से लौटा।

किसी भी प्रक्रिया से बाहर निकलें कोड - चाहे वह एक द्विआधारी निष्पादन योग्य हो, एक शेल स्क्रिप्ट, या कुछ और - 0 से 255 तक। यह एक बड़ा मूल्य पारित करना संभव है exit(), लेकिन केवल निम्न 8 बिट्स की स्थिति के लिए उपलब्ध हैं अन्य प्रक्रियाओं के माध्यम से wait()

  1. एग्जिट कोड एक फंक्शन (रिटर्न कॉलिंग) से लौटा है। मुझे लगता है कि यह 0 और 255 के बीच है।

एसी फ़ंक्शन को लगभग किसी भी प्रकार की वापसी के रूप में घोषित किया जा सकता है। इसके रिटर्न वैल्यू की सीमाएँ पूरी तरह से उस प्रकार से निर्धारित की जाती हैं: उदाहरण के लिए, -128 से 127 एक फंक्शन रिटर्निंग के लिए signed char, या फंक्शन रिटर्न के लिए 0 से 4.2 बिलियन unsigned int, या किसी फ़्लोटिंग-पॉइंट नंबर तक और infफंक्शन रिटर्निंग के लिए भी double। और वह गैर-संख्यात्मक प्रकारों की गिनती नहीं कर रहा है, जैसे void *या struct...

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