2008-12-26 17 views
5

मेरे पास कई स्वतंत्र निष्पादन योग्य पर्ल, PHP सीएलआई स्क्रिप्ट और सी ++ प्रोग्राम हैं जिनके लिए मुझे निकास त्रुटि कोड रणनीति विकसित करने की आवश्यकता है। इन कार्यक्रमों को PHP में exec() का उपयोग करने के लिए बनाए गए रैपर वर्ग का उपयोग करके अन्य प्रोग्रामों द्वारा बुलाया जाता है। तो, मैं एक त्रुटि कोड वापस पाने में सक्षम हो जाएगा। उस त्रुटि कोड के आधार पर, कॉलिंग स्क्रिप्ट को कुछ करने की आवश्यकता होगी।एक अच्छा लिनक्स निकास त्रुटि कोड रणनीति क्या है?

मैंने थोड़ा सा शोध किया है और ऐसा लगता है कि 1-254 (या शायद केवल 1-127) श्रेणी में कुछ भी उपयोगकर्ता द्वारा परिभाषित त्रुटि कोड के लिए उचित खेल हो सकता है।

मैं बस सोच रहा था कि अन्य लोगों ने इस स्थिति में त्रुटि प्रबंधन से कैसे संपर्क किया है।

उत्तर

8

एकमात्र सम्मेलन यह है कि आप सफलता के लिए 0 लौटाते हैं, और त्रुटि के लिए शून्य के अलावा कुछ और। सबसे प्रसिद्ध यूनिक्स प्रोग्राम विभिन्न रिटर्न कोड दस्तावेज करते हैं जिन्हें वे वापस कर सकते हैं, और आपको भी ऐसा करना चाहिए। यह सभी संभावित त्रुटि कोडों के लिए एक सामान्य सूची बनाने की कोशिश करने के लिए बहुत समझ में नहीं आता है कि कोई मनमाना प्रोग्राम वापस आ सकता है, या फिर आप tens of thousands of them like some other OS's के साथ समाप्त हो जाते हैं, और फिर भी, यह हमेशा विशिष्ट प्रकार को कवर नहीं करता है त्रुटि आप वापस करना चाहते हैं।

तो बस सुसंगत रहें, और जो भी योजना आप उपयोग करने का निर्णय लेते हैं उसे दस्तावेज करना सुनिश्चित करें।

6

1-127 उपलब्ध सीमा है। 127 से अधिक कुछ भी "असामान्य" निकास होना चाहिए - सिग्नल द्वारा समाप्त किया गया।

जब आप इसमें हों, तो निकास कोड के बजाय stdout का उपयोग करने पर विचार करें। बाहर निकलें कोड सफलता, विफलता, और एक अन्य राज्य का संकेत देने के लिए इस्तेमाल परंपरा द्वारा किया जाता है। बाहर निकलने के कोड का उपयोग करने के बजाय, exd और wc इसका उपयोग करने के तरीके stdout का उपयोग करने का प्रयास करें। इसके बाद आप परिणामों को निकालने के लिए कॉलर में बैकटिक या कुछ समान उपयोग कर सकते हैं।

+2

त्रुटि संदेशों के लिए stderr का उपयोग करें। – iny

+1

स्पष्ट होने के लिए, माता-पिता की प्रक्रिया के लिए यह हमेशा संभव है कि यह सिग्नल या सामान्य निकास हो ... यह _shell_ है जो '$?' के लिए 12 9-254 पर संकेतों को मानचित्र करता है। – Random832

3

यूनिक्स घोषणापत्र राज्यों -

बाहर निकलें रूप में जल्द ही और त्रुटि

या कि

2

की तरह कुछ पर संभव के रूप में जोर से भी ज्यादा अर्थ सांकेतिक शब्दों में बदलना की कोशिश मत करो बाहर निकलने के मूल्य में: विस्तृत स्थिति और त्रुटि रिपोर्ट stadout/stderr पर जाना चाहिए क्योंकि Arkadiy सुझाव देता है।

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

0000 : 0 (no error) 
0001 : 1 (error) 
0010 : 2 (I/O error) 
0100 : 4 (user input error) 
1000 : 8 (permission error) 

फिर, एक उपयोगकर्ता इनपुट त्रुटि 5 (4 + 1) के एक वापसी मान होता है, जबकि एक लॉग फ़ाइल लिखने की अनुमति वाले नहीं एक वापसी मान हो सकता है 11 (8 + 2 + 1) का। चूंकि अलग-अलग अर्थ वापसी मूल्य में स्वतंत्र रूप से एन्कोड किए जाते हैं, इसलिए आप आसानी से देख सकते हैं कि कौन से बिट सेट किए गए हैं यह जांच कर क्या हुआ है। यदि कोई त्रुटि आप कर सकते हैं और साथ 1.

वापसी कोड ऐसा करने से था

एक विशेष मामले के रूप में, देखने के लिए, आप वापसी कोड में अलग अलग बातें की एक जोड़ी सांकेतिक शब्दों में बदलना कर सकते हैं, एक स्पष्ट में और सरल तरीका। मैं इसे केवल सरल निर्णय लेने के लिए उपयोग करता हूं जैसे "प्रक्रिया को पुनरारंभ करना चाहिए", "वापसी मूल्य और प्रासंगिक लॉग को व्यवस्थापक को भेजने की आवश्यकता है", इस तरह की चीज। किसी भी विस्तृत नैदानिक ​​जानकारी को लॉग या stdout/stderr पर जाना चाहिए।

1

सामान्य निकास स्थिति 0 से 255 तक चलती है (क्यों देखें Exit codes bigger than 255 posssible क्यों चर्चा के लिए)। आम तौर पर, स्थिति 0 सफलता को इंगित करता है; कुछ और कार्यान्वयन-परिभाषित त्रुटि है। मुझे एक ऐसे कार्यक्रम के बारे में पता है जो बाहर निकलने की स्थिति के माध्यम से डीबीएमएस सर्वर की स्थिति की रिपोर्ट करता है; यह कार्यान्वयन-परिभाषित निकास स्थितियों का एक विशेष मामला है। ध्यान दें कि आप अपने कार्यक्रमों की स्थिति के कार्यान्वयन को परिभाषित करते हैं।

मैं इसे 300 वर्णों में फिट नहीं कर सका; अन्यथा यह @ Arkadiy के जवाब पर एक टिप्पणी होगी।

Arkadiy सही है कि निकास स्थिति शब्द के एक हिस्से में, शून्य के अलावा अन्य मान सिग्नल को इंगित करते हैं जो प्रक्रिया को समाप्त कर देता है और 8 वें बिट आमतौर पर कोर डंप इंगित करता है, लेकिन बाहर निकलने की स्थिति का वह भाग मुख्य से अलग होता है 0..255 स्थिति। हालांकि, एक सिग्नल के परिणामस्वरूप एक प्रक्रिया मर जाती है जब खोल (जो भी खोल यह है) एक समस्या के साथ प्रस्तुत किया जाता है। 8-बिट मान में 16 बिट्स डेटा प्रस्तुत किए जाने हैं, जो हमेशा मुश्किल होता है। लगता है कि गोले सिग्नल नंबर लेते हैं और इसमें 128 जोड़ते हैं। इसलिए, यदि कोई प्रक्रिया किसी इंटरप्ट (सिग्नल नंबर 2, सिगिनट) के परिणामस्वरूप मर जाती है, तो शेल बाहर निकलने की स्थिति 130 के रूप में रिपोर्ट करता है। हालांकि, कर्नेल ने स्थिति को 0x0002 के रूप में रिपोर्ट किया; खोल ने संशोधित किया है कि कर्नेल रिपोर्ट क्या करता है।

निम्नलिखित सी कोड यह दर्शाता है। दो कार्यक्रम

  • suicide जो आपके चयन के सिग्नल (डिफ़ॉल्ट रूप से बाधित) का उपयोग करके स्वयं को मारता है।
  • exitstatus जो एक आदेश चलाता है (जैसे suicide) और कर्नेल निकास स्थिति की रिपोर्ट करता है।

यहाँ suicide.c है:

/* 
@(#)File:   $RCSfile: suicide.c,v $ 
@(#)Version:  $Revision: 1.2 $ 
@(#)Last changed: $Date: 2008/12/28 03:45:18 $ 
@(#)Purpose:  Commit suicide using kill() 
@(#)Author:   J Leffler 
@(#)Copyright:  (C) JLSS 2008 
@(#)Product:  :PRODUCT: 
*/ 

/*TABSTOP=4*/ 

#if __STDC_VERSION__ >= 199901L 
#define _XOPEN_SOURCE 600 
#else 
#define _XOPEN_SOURCE 500 
#endif /* __STDC_VERSION__ */ 

#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include "stderr.h" 

static const char usestr[] = "[-V][-s signal]"; 

#ifndef lint 
/* Prevent over-aggressive optimizers from eliminating ID string */ 
extern const char jlss_id_suicide_c[]; 
const char jlss_id_suicide_c[] = "@(#)$Id: suicide.c,v 1.2 2008/12/28 03:45:18 jleffler Exp $"; 
#endif /* lint */ 

int main(int argc, char **argv) 
{ 
    int signum = SIGINT; 
    int opt; 
    char *end; 

    err_setarg0(argv[0]); 

    while ((opt = getopt(argc, argv, "Vs:")) != -1) 
    { 
     switch (opt) 
     { 
     case 's': 
      signum = strtol(optarg, &end, 0); 
      if (*end != '\0' || signum <= 0) 
       err_error("invalid signal number %s\n", optarg); 
      break; 
     case 'V': 
      err_version("SUICIDE", &"@(#)$Revision: 1.2 $ ($Date: 2008/12/28 03:45:18 $)"[4]); 
      break; 
     default: 
      err_usage(usestr); 
      break; 
     } 
    } 
    if (optind != argc) 
     err_usage(usestr); 
    kill(getpid(), signum); 
    return(0); 
} 

और यहाँ exitstatus.c है:

/* 
@(#)File:   $RCSfile: exitstatus.c,v $ 
@(#)Version:  $Revision: 1.2 $ 
@(#)Last changed: $Date: 2008/12/28 03:45:18 $ 
@(#)Purpose:  Run command and report 16-bit exit status 
@(#)Author:   J Leffler 
@(#)Copyright:  (C) JLSS 2008 
@(#)Product:  :PRODUCT: 
*/ 

/*TABSTOP=4*/ 

#if __STDC_VERSION__ >= 199901L 
#define _XOPEN_SOURCE 600 
#else 
#define _XOPEN_SOURCE 500 
#endif /* __STDC_VERSION__ */ 

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include "stderr.h" 

#ifndef lint 
/* Prevent over-aggressive optimizers from eliminating ID string */ 
extern const char jlss_id_exitstatus_c[]; 
const char jlss_id_exitstatus_c[] = "@(#)$Id: exitstatus.c,v 1.2 2008/12/28 03:45:18 jleffler Exp $"; 
#endif /* lint */ 

int main(int argc, char **argv) 
{ 
    pid_t pid; 

    err_setarg0(argv[0]); 

    if (argc < 2) 
     err_usage("cmd [args...]"); 

    if ((pid = fork()) < 0) 
     err_syserr("fork() failed: "); 
    else if (pid == 0) 
    { 
     /* Child */ 
     execvp(argv[1], &argv[1]); 
     return(1); 
    } 
    else 
    { 
     pid_t corpse; 
     int status; 
     corpse = waitpid(pid, &status, 0); 
     if (corpse != pid) 
      err_syserr("waitpid() failed: "); 
     printf("0x%04X\n", status); 
    } 
    return(0); 
} 

लापता कोड, stderr.c और stderr.h, आसानी से अपने प्रकाशित कार्यक्रमों की अनिवार्य रूप से किसी भी में पाया जा सकता। यदि आपको तत्काल इसकी आवश्यकता है, तो इसे IIUG Software Archive पर SQLCMD प्रोग्राम से प्राप्त करें; वैकल्पिक रूप से, ईमेल द्वारा मुझसे संपर्क करें (मेरी प्रोफ़ाइल देखें)।

संबंधित मुद्दे