क्या लिनक्स में कोई मानक निकास स्थिति कोड हैं?


308

एक प्रक्रिया को लिनक्स में सही ढंग से पूरा करने के लिए माना जाता है अगर इसकी निकास स्थिति 0 थी।

मैंने देखा है कि विभाजन दोषों का परिणाम अक्सर 11 से बाहर निकलने की स्थिति में होता है, हालांकि मुझे नहीं पता कि क्या यह केवल वह सम्मेलन है जहां मैं काम करता हूं (ऐसे ऐप्स जो इस तरह विफल हो गए हैं वे सभी आंतरिक हैं) या एक मानक।

क्या लिनक्स में प्रक्रियाओं के लिए मानक निकास कोड हैं?


6
अगर आप "सिस्टम एरर नंबर" नामक चीज़ की तलाश कर रहे हैं, जो सिस्टम फ़ंक्शंस द्वारा लौटाया गया है, यहाँ पर देख सकते हैं
मारिनारा

जवाबों:


86

वापसी कोड के 8 बिट्स और हत्या सिग्नल की संख्या के 8 बिट्स wait(2)& Co से वापसी पर एक ही मूल्य में मिश्रित होते हैं

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>

int main() {
    int status;

    pid_t child = fork();
    if (child <= 0)
        exit(42);
    waitpid(child, &status, 0);
    if (WIFEXITED(status))
        printf("first child exited with %u\n", WEXITSTATUS(status));
    /* prints: "first child exited with 42" */

    child = fork();
    if (child <= 0)
        kill(getpid(), SIGSEGV);
    waitpid(child, &status, 0);
    if (WIFSIGNALED(status))
        printf("second child died with %u\n", WTERMSIG(status));
    /* prints: "second child died with 11" */
}

आप बाहर निकलने की स्थिति कैसे निर्धारित कर रहे हैं? परंपरागत रूप से, शेल केवल 8-बिट रिटर्न कोड संग्रहीत करता है, लेकिन यदि प्रक्रिया असामान्य रूप से समाप्त हो गई थी, तो उच्च बिट सेट करता है।

$ श-सी 'निकास 42'; इको $?
42
$ श-सी 'किल -SEGV $$'; इको $?
विभाजन दोष
139
$ expr 139 - 128
1 1

यदि आप इसके अलावा कुछ भी देख रहे हैं, तो प्रोग्राम में संभवतः एक SIGSEGVसिग्नल हैंडलर है, जो तब exitसामान्य रूप से कॉल करता है , इसलिए यह वास्तव में सिग्नल द्वारा नहीं मारा जा रहा है। (प्रोग्राम किसी भी सिग्नल को एक तरफ से संभालने के लिए चुना जा सकता है SIGKILLऔर SIGSTOP)


8
जिस तरह से अब प्रश्न दिखाई देता है, उसे देखते हुए यह सबसे उपयोगी (और इस प्रकार स्वीकार किए गए) उत्तर के रूप में प्रकट नहीं होता है।
डेविड जे।

332

भाग 1: उन्नत बैश स्क्रिप्टिंग गाइड

हमेशा की तरह, एडवांस्ड बैश स्क्रिप्टिंग गाइड में बहुत अच्छी जानकारी है : (यह एक अन्य उत्तर में, लेकिन एक गैर-कैनन URL से जोड़ा गया था।)

1: सामान्य त्रुटियों के लिए कैटचेल
2: शेल बिल्डिंस का दुरुपयोग (बैश प्रलेखन के अनुसार)
126: कमांड आह्वान
127 को निष्पादित नहीं कर सकता है : "कमांड नहीं मिला"
128: 128 से बाहर निकलने के लिए अमान्य तर्क
+ n: घातक त्रुटि संकेत "n"
255: बाहर निकलें श्रेणी से बाहर की स्थिति (सीमा 0 से 255 में केवल पूर्णांक आर्ग लेती है)

भाग 2: sysexits.h

ABSG संदर्भ sysexits.h

लिनक्स पर:

$ find /usr -name sysexits.h
/usr/include/sysexits.h
$ cat /usr/include/sysexits.h

/*
 * Copyright (c) 1987, 1993
 *  The Regents of the University of California.  All rights reserved.

 (A whole bunch of text left out.)

#define EX_OK           0       /* successful termination */
#define EX__BASE        64      /* base value for error messages */
#define EX_USAGE        64      /* command line usage error */
#define EX_DATAERR      65      /* data format error */
#define EX_NOINPUT      66      /* cannot open input */    
#define EX_NOUSER       67      /* addressee unknown */    
#define EX_NOHOST       68      /* host name unknown */
#define EX_UNAVAILABLE  69      /* service unavailable */
#define EX_SOFTWARE     70      /* internal software error */
#define EX_OSERR        71      /* system error (e.g., can't fork) */
#define EX_OSFILE       72      /* critical OS file missing */
#define EX_CANTCREAT    73      /* can't create (user) output file */
#define EX_IOERR        74      /* input/output error */
#define EX_TEMPFAIL     75      /* temp failure; user is invited to retry */
#define EX_PROTOCOL     76      /* remote error in protocol */
#define EX_NOPERM       77      /* permission denied */
#define EX_CONFIG       78      /* configuration error */

#define EX__MAX 78      /* maximum listed value */

5
ध्यान दें कि यूनिक्स के कुछ स्वादों में, कुछ कमांड अन्य चीजों को इंगित करने के लिए 2 से बाहर निकलने की स्थिति का उपयोग करते हैं। उदाहरण के लिए, grep के कई कार्यान्वयन त्रुटि को इंगित करने के लिए 2 से बाहर निकलने की स्थिति का उपयोग करते हैं, और 1 की निकास स्थिति का उपयोग करने के लिए इसका मतलब है कि कोई चयनित रेखाएं नहीं मिलीं।
नेमसुबिटर

3
BSDs पर sysexits.h से जानकारी को सारांशित करते हुए एक आदमी पृष्ठ है:man sysexits
जार्जब्रुक

6
@ नमशभवर ने क्या कहा। एक्ज़िट स्टेटस 2 यूनिक्स उपयोगिताओं में गलत कमांड लाइन उपयोग के लिए सार्वभौमिक गो-इन है, न केवल "यूनिक्स के कुछ स्वादों" में बल्कि सामान्य रूप से। इस उत्तर में दिखाए गए शीर्षलेख वास्तविक सम्मेलनों को नहीं दर्शाते हैं, अब या जब यह 1987 में लिखा गया था।
एलेक्सिस

ABS "महान" नहीं है। कृपया विषय पर पढ़ें; आलोचनाओं को खोजना बिलकुल मुश्किल नहीं है।
ट्रिपलए

लेकिन वास्तविक आधिकारिक स्रोत कोड कहां है sysexits.h? आदमी पेज हर कोई संदर्भित सिर्फ गद्य है रहता है। उदाहरण के लिए यह संदर्भ देता है EX_OKलेकिन वास्तव में इसे अन्य कोड की तरह एक मानक तरीके से परिभाषित नहीं करता है। क्या और भी हैं जो गायब हैं?
गैरेट विल्सन

71

सामान्य त्रुटियों के लिए '1' >>> कैटचेल

'2' >>> शेल बिल्डरों का दुरुपयोग (बैश प्रलेखन के अनुसार)

'126' >>> कमांड द्वारा लागू नहीं किया जा सकता

"127 ' >>>" कमांड नहीं मिली "

'128' >>> बाहर निकलने के लिए अमान्य तर्क

"128 + n ' >>> घातक त्रुटि संकेत" n "

'130' >>> स्क्रिप्ट नियंत्रण-सी द्वारा समाप्त

'255' >>> सीमा से बाहर की स्थिति

यह बैश के लिए है। हालांकि, अन्य अनुप्रयोगों के लिए, अलग-अलग निकास कोड हैं।


1
ऐसा लग रहा है कि आप दोनों ने एक ही मिनट में जवाब दिया। तियान को आपके लिंक देखने और उन्हें चिपकाने के लिए बहुत तेज होना होगा।
नाथन फेलमैन

6
ध्यान दें कि 'कंट्रोल-सी पैदावार 130' सिग्नल एन के लिए '128 + एन' के अनुरूप है; control-C SIGINT बनाता है जो सिग्नल 2 है।
जोनाथन लेफ्लर

3
ऐसा लगता है कि बिना किसी कारण के ABS से चोरी हो गई। (हम बता सकते हैं क्योंकि ABS में गलत या कम से कम भ्रामक जानकारी है।)
tripleee

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

53

पुराने उत्तरों में से कोई भी सही ढंग से निकास स्थिति 2 का वर्णन नहीं करता है। वे जो दावा करते हैं, उसके विपरीत, स्थिति 2 वह है जो आपकी कमांड लाइन उपयोगिताओं को वास्तव में अनुचित रूप से वापस आने पर वापस आती है। (हां, एक उत्तर नौ साल पुराना हो सकता है, सैकड़ों अपवित्र हैं, और अभी भी गलत हैं।)

यहाँ सामान्य समाप्ति के लिए वास्तविक, लंबे समय से बाहर निकलने की स्थिति सम्मेलन है, अर्थात संकेत द्वारा नहीं:

  • स्थिति से बाहर निकलें 0: सफलता
  • स्थिति 1 से बाहर निकलें: "विफलता", जैसा कि कार्यक्रम द्वारा परिभाषित किया गया है
  • स्थिति 2 से बाहर निकलें: कमांड लाइन उपयोग त्रुटि

उदाहरण के लिए, diff0 यदि रिटर्न की तुलना की गई फाइलें समान हैं, और 1 यदि वे अलग-अलग हैं। लंबे समय से चली आ रही परंपरा के अनुसार, यूनिक्स प्रोग्राम एग्जिट स्टेटस 2 लौटाते हैं, जब गलत तरीके से कहा जाता है (अज्ञात विकल्प, तर्कों की गलत संख्या, आदि) उदाहरण के लिए diff -N, grep -Yया diff a b cसभी परिणाम 2 में $?सेट हो जाएंगे । यह है और तब से ही यह प्रथा है 1970 के दशक में यूनिक्स के शुरुआती दिन।

स्वीकार किए जाते हैं जवाब जब एक आदेश है कि क्या होता है बताते हैं एक संकेत द्वारा समाप्त। संक्षेप में, एक अनटूट सिग्नल के कारण समाप्ति की स्थिति से बाहर निकलने की स्थिति होती है 128+[<signal number>। उदाहरण के लिए, SIGINT( संकेत 2 ) द्वारा समाप्ति से बाहर निकलने की स्थिति 130 हो जाती है।

टिप्पणियाँ

  1. कई उत्तर निकास स्थिति 2 को "बैश बिल्डिंस का दुरुपयोग" के रूप में परिभाषित करते हैं। यह केवल तब लागू होता है जब बैश (या बैश स्क्रिप्ट) स्थिति से बाहर निकलती है 2. इसे गलत उपयोग की त्रुटि के विशेष मामले पर विचार करें।

  2. में sysexits.h, में उल्लेख किया सबसे लोकप्रिय जवाब , बाहर निकलें स्थिति EX_USAGE( "कमांड लाइन उपयोग त्रुटि") 64 होने के लिए परिभाषित किया गया है लेकिन यह करता है वास्तविकता नहीं दर्शाते हैं: मैं के बारे में पता नहीं कर रहा हूँ किसी भी आम यूनिक्स उपयोगिता है कि गलत मंगलाचरण पर रिटर्न 64 (उदाहरण का स्वागत करते हैं )। स्रोत कोड के सावधानीपूर्वक पढ़ने से पता चलता है कि sysexits.hयह सही उपयोग के प्रतिबिंब के बजाय, आकांक्षात्मक है:

     *    This include file attempts to categorize possible error
     *    exit statuses for system programs, notably delivermail
     *    and the Berkeley network.
    
     *    Error numbers begin at EX__BASE [64] to reduce the possibility of 
     *    clashing with oth­er exit statuses that random programs may 
     *    already return. 
    

    दूसरे शब्दों में, ये परिभाषा उस समय (1993) के सामान्य अभ्यास को नहीं दर्शाती है, लेकिन इसके साथ जानबूझकर असंगत थे। मोर की दया।


जब यह SIGINT / Ctrl-C को पकड़कर समाप्ति को नियंत्रित करता है, तो एक कार्यक्रम क्या लौटना चाहिए ? अभी भी 130? क्या बाश पदार्थ के अलावा एक और शेल का उपयोग किया जाता है?
ग्रिंगो सुव

1
प्रोग्राम को निष्पादित करने वाला शेल अप्रासंगिक है; एक प्रक्रिया सैद्धांतिक रूप से अपनी मूल प्रक्रिया के आधार पर अलग-अलग स्थिति के साथ बाहर निकलने का विकल्प चुन सकती है, लेकिन मैंने कभी ऐसा मामला नहीं सुना, जहां ऐसा होता हो।
एलेक्सिस

1
यदि कोई प्रोग्राम SIGINT को पकड़ता है, वैसे भी साफ करता है, और बाहर निकलता है, तो जो भी स्थिति है वह प्रोग्राम के लिए समझ में आता है। उदाहरण के लिए, moreटर्मिनल मोड को रीसेट करेगा और स्टेटस 0 से बाहर निकल जाएगा (आप इसे आज़मा सकते हैं)।
एलेक्सिस

1
यह जवाब वास्तव में मामला है की तुलना में मानकीकरण का एक बहुत उच्च ग्रेड का मतलब है। मूल्य 2 के अर्थ का कोई उचित मानकीकरण नहीं है, और वास्तविक अभ्यास तो अनुमानित रूप से बहुत मिश्रित है। यह सच है कि कई उपकरण अनुचित उपयोग के लिए 2 लौटाते हैं, लेकिन यह बिल्कुल अच्छी तरह से परिभाषित नहीं है कि "अनुचित उपयोग" का क्या मतलब है, और कई अन्य इस सम्मेलन का पालन नहीं करते हैं।
ट्रिपलए

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

25

0 अर्थ सफलता से अलग कोई मानक निकास कोड नहीं हैं। गैर-शून्य जरूरी नहीं कि विफलता का मतलब है।

stdlib.h EXIT_FAILURE1 और EXIT_SUCCESS0 के रूप में परिभाषित करता है , लेकिन यह इसके बारे में है।

सेगफॉल्ट पर 11 दिलचस्प है, क्योंकि 11 सिग्नल संख्या है जो कि गिरी एक सेगफॉल्ट की स्थिति में प्रक्रिया को मारने के लिए उपयोग करता है। कुछ तंत्र की संभावना है, या तो कर्नेल में या शेल में, जो कि बाहर निकलने वाले कोड में अनुवाद करता है।


20

sysexits.h में मानक निकास कोड की एक सूची है। यह कम से कम 1993 में वापस की तारीख लगता है और पोस्टफिक्स जैसी कुछ बड़ी परियोजनाएं इसका उपयोग करती हैं, इसलिए मुझे लगता है कि यह जाने का रास्ता है।

OpenBSD मैन पेज से:

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

8

पहले सन्निकटन के लिए, 0 सक्सेज है, नॉन-जीरो फेल है, जिसमें 1 सामान्य फेल्योर है, और एक विशिष्ट फेल होने से बड़ा कुछ भी नहीं है। झूठे और परीक्षण के तुच्छ अपवादों के अलावा, जो दोनों को सक्सेज के लिए 1 देने के लिए डिज़ाइन किए गए हैं, कुछ और अपवाद हैं जो मुझे मिले।

अधिक वास्तविक रूप से, 0 का अर्थ है सक्सेज या हो सकता है असफलता, 1 का अर्थ है सामान्य असफलता या शायद सक्सेज, 2 का अर्थ सामान्य विफलता है यदि 1 और 0 दोनों सक्सेज के लिए उपयोग किए जाते हैं, लेकिन शायद सक्सेज भी।

डिफाइन कमांड 0 देता है यदि तुलना की गई फाइलें समान हैं, 1 यदि वे भिन्न हैं, और 2 यदि बायनेरी भिन्न हैं। 2 का मतलब असफलता भी है। कम आदेश विफलता के लिए 1 देता है जब तक कि आप एक तर्क की आपूर्ति करने में विफल नहीं होते हैं, उस स्थिति में, यह विफल होने के बावजूद 0 से बाहर निकलता है।

अधिक कमांड और स्पेल कमांड विफलता के लिए 1 देता है, जब तक कि विफलता अस्वीकार की गई अनुमति, परिणामहीन फाइल या निर्देशिका को पढ़ने का प्रयास न हो। इनमें से किसी भी मामले में, वे असफल होने के बावजूद 0 से बाहर निकलते हैं।

तब expr कमांड sucess के लिए 1 देता है जब तक कि आउटपुट खाली स्ट्रिंग या शून्य नहीं होता है, उस स्थिति में, 0 sucess है। 2 और 3 फेल हैं।

फिर ऐसे मामले हैं जहां सफलता या विफलता अस्पष्ट है। जब grep एक पैटर्न खोजने में विफल रहता है, तो यह 1 से बाहर निकलता है, लेकिन यह वास्तविक विफलता के लिए 2 से बाहर निकलता है (जैसे अनुमति अस्वीकृत)। किस्टल भी 1 से बाहर निकलता है जब वह एक टिकट खोजने में विफल रहता है, हालांकि यह वास्तव में विफलता की तुलना में कोई अधिक नहीं है जब grep एक पैटर्न नहीं ढूंढता है, या जब आप एक खाली निर्देशिका प्राप्त करते हैं।

इसलिए, दुर्भाग्य से, यूनिक्स शक्तियां नियमों के किसी भी तार्किक सेट को लागू करने के लिए प्रतीत नहीं होती हैं, यहां तक ​​कि बहुत ही आमतौर पर उपयोग किए जाने वाले निष्पादन पर भी।


मैं अलग व्यवहार को भी इंगित करने वाला था। wget में भी विस्तृत त्रुटियां हैं (जैसे प्रमाणीकरण विफलता के लिए 6), लेकिन फिर वे 1 = सामान्य त्रुटि, 2..n = विशिष्ट त्रुटि का उपयोग करते हैं
PypeBros

5

प्रोग्राम 16 बिट एक्जिट कोड लौटाते हैं। यदि प्रोग्राम एक सिग्नल के साथ मारा गया था, तो उच्च ऑर्डर बाइट में सिग्नल का उपयोग किया जाता है, अन्यथा कम ऑर्डर बाइट प्रोग्रामर द्वारा लौटाए गए निकास की स्थिति है।

उस एग्जिट कोड को स्टेटस वैरिएबल $ को कैसे सौंपा जाता है? फिर खोल तक है। बैश स्थिति के निचले 7 बिट्स को रखता है और फिर सिग्नल को दर्शाने के लिए 128 + (सिग्नल एनआर) का उपयोग करता है।

कार्यक्रमों के लिए एकमात्र "मानक" सम्मेलन सफलता के लिए 0 है, त्रुटि के लिए गैर-शून्य। गलती पर ग़लती पर लौटने के लिए उपयोग किया गया एक और सम्मेलन है।


3

मानक यूनिक्स निकास कोड sysexits.h द्वारा परिभाषित किए गए हैं, जैसा कि एक और पोस्टर में उल्लेख किया गया है। समान निकास कोड पोर्टेबल लाइब्रेरी जैसे कि पोको - द्वारा उपयोग किए जाते हैं - यहां उनकी एक सूची है:

http://pocoproject.org/docs/Poco.Util.Application.html#16218

सिग्नल 11 एक SIGSEGV (खंड उल्लंघन) संकेत है, जो एक रिटर्न कोड से अलग है। यह सिग्नल खराब पेज एक्सेस के जवाब में कर्नेल द्वारा उत्पन्न होता है, जो प्रोग्राम को समाप्त करने का कारण बनता है। सिग्नल की एक सूची सिग्नल मैन पेज में मिल सकती है ("मैन सिग्नल" चलाएं)।


1

जब लिनक्स 0 देता है, तो इसका मतलब है कि सफलता। कुछ भी और असफलता का मतलब है, प्रत्येक कार्यक्रम के अपने निकास कोड हैं, इसलिए उन सभी को सूचीबद्ध करने के लिए काफी लंबा होगा ...!

11 त्रुटि कोड के बारे में, यह वास्तव में विभाजन की गलती संख्या है, जिसका अर्थ है कि कार्यक्रम एक मेमोरी स्थान पर पहुंच गया है जिसे असाइन नहीं किया गया था।


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