Coder Perfect

In Linux, are there any standard exit status codes?

Problem

In Linux, a process is regarded to have completed successfully if its exit status is 0.

I’ve seen that segmentation faults often result in an exit status of 11, though I don’t know if this is simply the convention where I work (the apps that failed like that have all been internal) or a standard.

In Linux, are there any standard exit codes for processes?

Asked by Nathan Fellman

Solution #1

As usual, the Advanced Bash Scripting Guide is jam-packed with useful information: (Another response linked to this, but it was a non-canonical URL.)

sysexits.h is mentioned in the ABSG.

On Linux:

$ 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 */

Answered by Schof

Solution #2

On the return from wait(2) & co., the return code and the number of the killing signal are combined into a single value.

#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" */
}

What method are you using to determine the exit status? Traditionally, the shell merely maintains an 8-bit return code, however if the process was terminated abnormally, the high bit is set.

$ sh -c 'exit 42'; echo $?
42
$ sh -c 'kill -SEGV $$'; echo $?
Segmentation fault
139
$ expr 139 - 128
11

If you see anything else, the program most likely contains a SIGSEGV signal handler, which subsequently calls exit normally, indicating that the signal isn’t actually killing it. (Apart from SIGKILL and SIGSTOP, programs can choose to handle any signal.)

Answered by ephemient

Solution #3

>>> ‘1’ This is a catch-all for all types of errors.

‘2’ >>> Inappropriate usage of shell builtins (according to Bash documentation)

‘126’>>> The command that was issued could not be carried out.

‘127’>>>”command not found”

‘128’>>> Exit argument is invalid.

‘128+n’>>>’n’>>>’n’>>>’n’>>>’n’>>>’n’>>>’n’

‘130’>>> Control-C terminated the script.

‘255’>>> Exit status is no longer valid.

This is for the purpose of bash. Other programs, on the other hand, have distinct exit codes.

Answered by segfault

Solution #4

None of the previous responses accurately explain exit status 2. Status 2 is what your command line utilities truly return when called incorrectly, despite what they state. (Yes, even if an answer is nine years old and has hundreds of upvotes, it can still be incorrect.)

For natural termination, i.e. not via signal, this is the true, long-standing exit status convention:

If the files being compared are identical, diff returns 0; otherwise, it returns 1. When unix applications are called erroneously, they return exit status 2 as a long-standing convention (unknown options, wrong number of arguments, etc.) diff -N, grep -Y, and diff a b c, for example, all result in $? being set to 2. This has been the standard since the 1970s, when Unix was first introduced.

When a command is terminated by a signal, the approved answer specifies what happens. In a nutshell, uncaught signal termination results in exit status 128+[signal number>]. E.g., termination by SIGINT (signal 2) results in exit status 130.

Answered by alexis

Solution #5

Aside from 0 indicating success, there are no conventional exit codes. In addition, non-zero does not always imply failure.

EXIT FAILURE is defined as 1 and EXIT SUCCESS is defined as 0, but that’s about it in stdlib.h.

The 11 on segfault is significant since 11 is the signal number used by the kernel to end a process when it segfaults. There’s probably a mechanism somewhere, either in the kernel or in the shell, that converts that to an exit code.

Answered by Chris Arguin

Post is based on https://stackoverflow.com/questions/1101957/are-there-any-standard-exit-status-codes-in-linux