代码之家  ›  专栏  ›  技术社区  ›  Chris Kloberdanz

什么是好的Linux退出错误代码策略?

  •  5
  • Chris Kloberdanz  · 技术社区  · 17 年前

    我有几个独立的可执行Perl,PHP CLI脚本和C++程序,我需要开发出一个退出错误代码策略。这些程序由使用我创建的包装类的其他程序调用 exec()

    我做了一点研究,似乎在1-254(或者可能只是1-127)范围内的任何东西都可以公平地对待用户定义的错误代码。

    我只是想知道在这种情况下,其他人是如何处理错误的。

    5 回复  |  直到 17 年前
        1
  •  8
  •   Nik Reiman    17 年前

    tens of thousands of them like some other OS's ,即使如此,它也不总是覆盖您想要返回的特定类型的错误。

    所以,只要保持一致,并确保记录您决定使用的任何方案。

        2
  •  6
  •   user3458 user3458    17 年前

    1-127是可用范围。任何超过127的都被认为是“异常”退出——由信号终止。

        3
  •  4
  •   theman_on_vista theman_on_vista    17 年前

    unix宣言声明-

    出现错误时,请尽快大声退出

        4
  •  2
  •   James Brady    17 年前

    不要试图编码 退出值有很多意义:按照Arkadiy的建议,详细的状态和错误报告应该转到stdout/stderr。

    然而,我发现在出口值中仅表示少数状态非常有用,使用二进制数字对它们进行编码。例如,假设您具有以下人为含义:

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

    作为一种特殊情况,要查看是否存在错误,可以使用1和返回代码。

    通过这样做,您可以在返回代码中以清晰、简单的方式编码两种不同的内容。我用它来做一些简单的决定,比如“是否应该重新启动进程”,“返回值和相关日志是否需要发送给管理员”,诸如此类的事情。任何详细的诊断信息都应转至日志或stdout/stderr。

        5
  •  1
  •   Community Mohan Dere    9 年前

    正常退出状态从0到255(请参阅 Exit codes bigger than 255 posssible 讨论原因)。正常情况下,状态0表示成功;其他任何内容都是实现定义的错误。我确实知道有一个程序通过退出状态报告DBMS服务器的状态;这是实现定义的退出状态的特例。请注意,您需要定义程序状态的实现。

    Arkadiy是正确的,在退出状态字的一部分中,除0以外的值表示终止进程的信号,第8位通常表示核心转储,但退出状态的该部分与主0..255状态不同。然而,当进程因信号而死亡时,外壳(无论是哪个外壳)会出现问题。在8位值中要显示16位数据,这总是很棘手的。Shell所做的似乎是获取信号号并向其添加128。因此,如果进程由于中断(信号号2,SIGINT)而死亡,shell将报告退出状态为130。但是,内核报告状态为0x0002;shell修改了内核报告的内容。

    下面的C代码演示了这一点。有两个节目

    • suicide
    • exitstatus 运行命令(例如 )并报告内核退出状态。

    这是 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