Are there any standard exit status codes in Linux?
Asked Answered
W

12

384

A process is considered to have completed correctly in Linux if its exit status was 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 applications that failed like that have all been internal) or a standard.

Are there standard exit codes for processes in Linux?

Wrench answered 9/7, 2009 at 5:24 Comment(1)
if you're looking for the thing called "system error number" returned by system functions look here at errnoThirsty
C
95

8 bits of the return code and 8 bits of the number of the killing signal are mixed into a single value on the return from 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" */
}

How are you determining the exit status? Traditionally, the shell only stores an 8-bit return code, but sets the high bit if the process was abnormally terminated.

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

If you're seeing anything other than this, then the program probably has a SIGSEGV signal handler which then calls exit normally, so it isn't actually getting killed by the signal. (Programs can chose to handle any signals aside from SIGKILL and SIGSTOP.)

Chiffchaff answered 9/7, 2009 at 15:28 Comment(1)
Given the way the question now appears, this does not appear to be the most useful (and thus accepted) answer.Ultranationalism
M
389

Part 1: Advanced Bash Scripting Guide

As always, the Advanced Bash Scripting Guide has great information: (This was linked in another answer, but to a non-canonical URL.)

1: Catchall for general errors
2: Misuse of shell builtins (according to Bash documentation)
126: Command invoked cannot execute
127: "command not found"
128: Invalid argument to exit
128+n: Fatal error signal "n"
255: Exit status out of range (exit takes only integer args in the range 0 - 255)

Part 2: sysexits.h

The ABSG references sysexits.h.

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 */
Mississippian answered 8/10, 2009 at 5:8 Comment(6)
Note that in some flavors of unix, some commands use an exit status of 2 to indicate other things. For instance, many implementations of grep use an exit status of 2 to indicate an error, and use an exit status of 1 to mean that no selected lines were found.Taneka
On BSDs there's a man page summarising the info from sysexits.h: man sysexitsPetrillo
What @Taneka said. Exit status 2 is the universal go-to for incorrect command line usage in Unix utilities, not just in "some flavors of unix" but in general. The header shown in this answer does not reflect actual conventions, now or when it was written in 1987.Thermos
The ABS is not "great". Please read up on the subject; it's not exactly hard to find criticisms.Diligence
But where is the actual official source code for sysexits.h? The man page everybody keeps referencing is just prose. For example it references EX_OK but doesn't actually define it in a normative way like the other codes. Are there more that are missing?Iodic
@Schof, ...the Wooledge BashGuide was written specifically because the denizens of freenode's #bash channel got fed up trying to un-teach bad practices and outright incorrect information others had learned from the ABS. (Some of the outright inaccuracies have been cleaned up, but it's still rife with bad-practice examples today, and its maintainers have been entirely unwilling to defend or update content in response to critique).Noah
T
100

None of the older answers describe exit status 2 correctly. Contrary to what they claim, status 2 is what your command line utilities actually return when called improperly. (Yes, an answer can be nine years old, have hundreds of upvotes, and still be wrong.)

Here is the real, long-standing exit status convention for normal termination, i.e. not by signal:

  • Exit status 0: success
  • Exit status 1: "failure", as defined by the program
  • Exit status 2: command line usage error

For example, diff returns 0 if the files it compares are identical, and 1 if they differ. By long-standing convention, unix programs return exit status 2 when called incorrectly (unknown options, wrong number of arguments, etc.) For example, diff -N, grep -Y or diff a b c will all result in $? being set to 2. This is and has been the practice since the early days of Unix in the 1970s.

The accepted answer explains what happens when a command is terminated by a signal. In brief, termination due to an uncaught signal results in exit status 128+[<signal number>. E.g., termination by SIGINT (signal 2) results in exit status 130.

Notes

  1. Several answers define exit status 2 as "Misuse of bash builtins". This applies only when bash (or a bash script) exits with status 2. Consider it a special case of incorrect usage error.

  2. In sysexits.h, mentioned in the most popular answer, exit status EX_USAGE ("command line usage error") is defined to be 64. But this does not reflect reality: I am not aware of any common Unix utility that returns 64 on incorrect invocation (examples welcome). Careful reading of the source code reveals that sysexits.h is aspirational, rather than a reflection of true usage:

     *    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. 
    

    In other words, these definitions do not reflect the common practice at the time (1993) but were intentionally incompatible with it. More's the pity.

Thermos answered 8/11, 2016 at 10:33 Comment(19)
What should a program return when it does handle termination by catching SIGINT/Ctrl-C? Still 130? Does use of another shell besides bash matter?Punkie
The shell that is executing the program is irrelevant; a process could theoretically choose to exit with different status depending on its parent process, but I've never, ever heard of a case where this happens.Thermos
If a program catches SIGINT, cleans up, and exits anyway, the status is whatever makes sense for the program. For example, more will reset the terminal modes and exit with status 0 (you can try it).Thermos
This answer implies a much higher grade of standardization than what is actually the case. There is no proper standardization of the meaning of the value 2, and actual practice is then predictably very mixed. It is true that many tools return 2 for improper usage but it's not exactly well-defined what "improper usage" means, and many others do not adhere to this convention.Diligence
@Diligence "tools" is not well-defined either! :-) Sure, anyone can write a command-line program and it can return anything at all, but the old-school "Unix command-line utilities" that have been around longer than Linux, or the contents of GNU coreutils, are quite consistent on this. If you think otherwise, please name some tools in this group that don't use status 2 this way. Also, "improper usage" is your term (and I agree it's a vague term); I wrote "command line usage error", which is pretty specific: non-existent or incompatible options, wrong number of non-option arguments, etc.Thermos
Not very compelling, but Heirloom diff says "2 for trouble" (sic). I'll keep looking and will get back to you when I have some examples.Diligence
Yeah that's a bit elliptical :'-). But this example is entirely consistent with what I'm saying: In context, "trouble" here clearly means "diff cannot run" (and therefore cannot decide whether or not there are differences). And "trouble" with normal termination generally translates to invalid flags, file not found, or whatever the matter is that prevents diff from running.Thermos
And indeed, check the source code: github.com/kallisti5/heirloom/blob/master/diff/diff.c . Exit status 2 when the program fails (flag errors but also files too large).Thermos
You claim that the highly voted answer is wrong yet at the same time could only provide a convention.Piotrowski
@konsolebox, what did you expect? There is no standard, the convention is precisely what we've got. sysexits.h was and is purely aspirational.Thermos
@Thermos So what's wrong about the other answer again? Take note the the question is "Are there any standard exit status codes in Linux?". Taking that into account your answer is actually the one that's invalid.Piotrowski
@Thermos sysexits.h is a widely used definition and is almost synonymous to a standard. At the very least it's a stronger "standard" than the convention you mentioned. It still doesn't make sense how you could just blatantly describe it as wrong.Piotrowski
Um, if you know of any standand Unix utilities that follow this "widely used definition", please list them here.Thermos
If you are depending on a specific value for a utility unless it is documented (not in code, but in the man page) then you can't rely on it. POSIX lists specific exit status' for certain utilities, as an example. Replying on 2 meaning X or 64 meaning X or any number to mean X is not safe.Jeffries
On my system, mkdir --xyz, mv --xyz, and cp --xyz all return exit code 1. bash --xyz and cd --xyz, on the other hand, return exit code 2.Pheidippides
Thanks for the report, @rrr. What is "your system"? On my OS X box your three commands return 64, bash returns 2 (Incidentally cd is a built-in, so it doesn't actually return a process exit code; but bash updates the exit status variable$? on its behalf... to 1, for your example.) So indeed there's not a lot of consistency out there...Thermos
@Thermos GNU/Linux. Stardard GNU tools.Pheidippides
@Thermos Not many but there's still a few like flock and lckdo. But then again this is not a question of wide usage or convention but a standard. If you consider values in a known header wrong with respect to the question then much worse is your convention. Disclaimer: I don't dis-acknowledge the common convention. It's just that compared to the other answer, a convention is a less applicable answer.Piotrowski
@Thermos Am I reading this right: you actually see standard utilities return 64 (sysexits.h EX_USAGE) on your very own box, and yet you say no utilities do it? sysexits.h is a BSD thing, so naturally you want to look at BSD to see it used. A quick search in FreeBSD’s GitHub mirror produces more than 150 hits.Babiche
C
95

8 bits of the return code and 8 bits of the number of the killing signal are mixed into a single value on the return from 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" */
}

How are you determining the exit status? Traditionally, the shell only stores an 8-bit return code, but sets the high bit if the process was abnormally terminated.

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

If you're seeing anything other than this, then the program probably has a SIGSEGV signal handler which then calls exit normally, so it isn't actually getting killed by the signal. (Programs can chose to handle any signals aside from SIGKILL and SIGSTOP.)

Chiffchaff answered 9/7, 2009 at 15:28 Comment(1)
Given the way the question now appears, this does not appear to be the most useful (and thus accepted) answer.Ultranationalism
G
79

'1': Catch-all for general errors

'2': Misuse of shell builtins (according to Bash documentation)

'126': Command invoked cannot execute

'127': "command not found"

'128': Invalid argument to exit

'128+n': Fatal error signal "n"

'130': Script terminated by Ctrl + C

'255': Exit status out of range

This is for Bash. However, for other applications, there are different exit codes.

Gibbet answered 9/7, 2009 at 5:28 Comment(4)
It look like you both answered in the same minute. Tian would have to be pretty quick to see your links and paste them in.Wrench
Note that 'control-C yields 130' is consistent with '128+n' for signal n; control-C generates SIGINT which is signal 2.Levina
This seems to be plagiarized from the ABS without attribution. (We can tell because the ABS contains incorrect or at least misleading information.)Diligence
These are RESERVED exit codes, according the Advanced Bash-Scripting Guide. That means these values should therefore be avoided for user-specified exit parameters.Huxley
B
24

There are no standard exit codes, aside from 0 meaning success. Non-zero doesn't necessarily mean failure either.

Header file stdlib.h does define EXIT_FAILURE as 1 and EXIT_SUCCESS as 0, but that's about it.

The 11 on segmentation fault is interesting, as 11 is the signal number that the kernel uses to kill the process in the event of a segmentation fault. There is likely some mechanism, either in the kernel or in the shell, that translates that into the exit code.

Benzene answered 9/7, 2009 at 5:29 Comment(2)
It's simply false to state that there are no standard exit codes. The manpage for wait(2) lists macros for decoding exit status, and the header file sysexits.h standardizes additional integer constants besides 0 and 1.Poock
The macros in wait(2) are specific to the "wstatus" from wait, which is wrapping up extra stuff. Note that one of those macros is defined as " WEXITSTATUS(wstatus) - returns the exit status of the child. ". That is the status that I understood us to be talking about. sysexits.h is interesting, but I'd say it doesn't have widespread usage. So yes, it is perhaps a standard, and worth keeping in mind for new work... but I wouldn't assume any given program complies to it.Benzene
C
23

Header file sysexits.h has a list of standard exit codes. It seems to date back to at least 1993 and some big projects like Postfix use it, so I imagine it's the way to go.

From the OpenBSD man page:

According to style(9), it is not good practice to call exit(3) with arbitrary values to indicate a failure condition when ending a program. Instead, the predefined exit codes from sysexits should be used, so the caller of the process can get a rough estimation about the failure class without looking up the source code.
Cierracig answered 9/7, 2009 at 5:56 Comment(0)
C
14

To a first approximation, 0 is success, non-zero is failure, with 1 being general failure, and anything larger than one being a specific failure. Aside from the trivial exceptions of false and test, which are both designed to give 1 for success, there's a few other exceptions I found.

More realistically, 0 means success or maybe failure, 1 means general failure or maybe success, 2 means general failure if 1 and 0 are both used for success, but maybe success as well.

The diff command gives 0 if files compared are identical, 1 if they differ, and 2 if binaries are different. 2 also means failure. The less command gives 1 for failure unless you fail to supply an argument, in which case, it exits 0 despite failing.

The more command and the spell command give 1 for failure, unless the failure is a result of permission denied, nonexistent file, or attempt to read a directory. In any of these cases, they exit 0 despite failing.

Then the expr command gives 1 for success unless the output is the empty string or zero, in which case, 0 is success. 2 and 3 are failure.

Then there's cases where success or failure is ambiguous. When grep fails to find a pattern, it exits 1, but it exits 2 for a genuine failure (like permission denied). klist also exits 1 when it fails to find a ticket, although this isn't really any more of a failure than when grep doesn't find a pattern, or when you ls an empty directory.

So, unfortunately, the Unix powers that be don't seem to enforce any logical set of rules, even on very commonly used executables.

Chiffon answered 10/6, 2015 at 5:20 Comment(1)
I was about to point out diff's behaviour too. wget also has detailed errors (e.g. 6 for authentication failure), but then they use 1 = generic error, 2..n = specific errorMassa
R
5

Programs return a 16 bit exit code. If the program was killed with a signal then the high order byte contains the signal used, otherwise the low order byte is the exit status returned by the programmer.

How that exit code is assigned to the status variable $? is then up to the shell. Bash keeps the lower 7 bits of the status and then uses 128 + (signal nr) for indicating a signal.

The only "standard" convention for programs is 0 for success, non-zero for error. Another convention used is to return errno on error.

Rosenberger answered 9/7, 2009 at 5:43 Comment(2)
Everyone else says 8 bits. Can you provide a source?Tedious
The accepted answer says the same thing as I am, which is 8 bits are status and 8 bits are signals. It was a long time ago that I wrote this answer, so I can't remember the source I used :-).Rosenberger
C
4

Standard Unix exit codes are defined by sysexits.h, as David mentioned. The same exit codes are used by portable libraries such as Poco - here is a list of them:

Class Poco::Util::Application, ExitCode

A signal 11 is a SIGSEGV (segment violation) signal, which is different from a return code. This signal is generated by the kernel in response to a bad page access, which causes the program to terminate. A list of signals can be found in the signal man page (run "man signal").

Cataract answered 9/7, 2009 at 6:54 Comment(1)
The source says "4.3BSD <sysexits.h> header file". Is it a POSIX thing?Evidently
G
1

Some are convention, but some other reserved ones are part of POSIX standard.

126 -- A file to be executed was found, but it was not an executable utility.

127 -- A utility to be executed was not found.

>128 -- A command was interrupted by a signal.

See the section RATIONALE of man 1p exit.

Gutbucket answered 8/2, 2023 at 12:36 Comment(0)
K
0

When Linux returns 0, it means success. Anything else means failure. Each program has its own exit codes, so it would been quite long to list them all...!

About the 11 error code, it's indeed the segmentation fault number, mostly meaning that the program accessed a memory location that was not assigned.

Kilovolt answered 9/7, 2009 at 5:28 Comment(1)
It's always 11 because the kernel kills it and assigns the "exit value." Likewise, other types of Faults will always get the same exit value.Hackberry
P
-1

You can check below list of common exit codes for Linux Shell Scripts. Below is attached the Link for more info: Hope this would help someone to debug quickly.

0   Success
1   Operation not permitted
2   No such file or directory
3   No such process
4   Interrupted sys
5   Input/output error
6   No such device or address
7   Argument list too long
8   Exec format error
9   Bad file descriptor
10  No child processes
11  Resource temporarily unavailable
12  Cannot allocate memory
13  Permission denied
14  Bad address
15  Block device required
16  Device or resource busy
17  File exists
18  Invalid cross-device link
19  No such device
20  Not a directory
21  Is a directory
22  Invalid argument
23  Too many open files in system
24  Too many open files
25  Inappropriate ioctl for device
26  Text file busy
27  File too large
28  No space left on device
29  Illegal seek
30  Read-only file system
31  Too many links
32  Broken pipe
33  Numerical argument out of domain
34  Numerical result out of range
35  Resource deadlock avoided
36  File name too long
37  No locks available
38  Function not implemented
39  Directory not empty
40  Too many levels of symbolic links
42  No message of desired type
43  Identifier removed
44  Channel number out of range
45  Level 2 not synchronized
46  Level 3 halted
47  Level 3 reset
48  Link number out of range
49  Protocol driver not attached
50  No CSI structure available
51  Level 2 halted
52  Invalid exchange
53  Invalid request descriptor
54  Exchange full
55  No anode
56  Invalid request code
57  Invalid slot
59  Bad font file format
60  Device not a stream
61  No data available
62  Timer expired
63  Out of streams resources
64  Machine is not on the network
65  Package not installed
66  Object is remote
67  Link has been severed
68  Advertise error
69  Srmount error
70  Communication error on send
71  Protocol error
72  Multihop attempted
73  RFS specific error
74  Bad message
75  Value too large for defined data type
76  Name not unique on network
77  File descriptor in bad state
78  Remote address changed
79  Can not access a needed shared library
80  Accessing a corrupted shared library
81  .lib section in a.out corrupted
82  Attempting to link in too many shared libraries
83  Cannot exec a shared library directly
84  Invalid or incomplete multibyte or wide character
85  Interrupted system call should be restarted
86  Streams pipe error
87  Too many users
88  Socket operation on non-socket
89  Destination address required
90  Message too long
91  Protocol wrong type for socket
92  Protocol not available
93  Protocol not supported
94  Socket type not supported
95  Operation not supported
96  Protocol family not supported
97  Address family not supported by protocol
98  Address already in use
99  Cannot assign requested address
100 Network is down
101 Network is unreachable
102 Network dropped connection on reset
103 Software caused connection abort
104 Connection reset by peer
105 No buffer space available
106 Transport endpoint is already connected
107 Transport endpoint is not connected
108 Cannot send after transport endpoint shutdown
109 Too many references
110 Connection timed out
111 Connection refused
112 Host is down
113 No route to host
114 Operation already in progress
115 Operation now in progress
116 Stale file handle
117 Structure needs cleaning
118 Not a XENIX named type file
119 No XENIX semaphores available
120 Is a named type file
121 Remote I/O error
122 Disk quota exceeded
123 No medium found
125 Operation canceled
126 Required key not available
127 Key has expired
128 Key has been revoked
129 Key was rejected by service
130 Owner died
131 State not recoverable
132 Operation not possible due to RF-kill
133 Memory page has hardware error

https://www.cyberciti.biz/faq/linux-bash-exit-status-set-exit-statusin-bash/

Printmaking answered 6/5, 2023 at 5:30 Comment(1)
This is an utter nonsense. Instead of process exit codes, the list is of errno codes. They are totally unrelated.Betook

© 2022 - 2024 — McMap. All rights reserved.