44

Is there a way I can do what stated in the title from the terminal commands, or will I have to look into the codes?

4 Answers 4

37

Exit codes indicate success or failure when ending a program, and they fall between 0 and 255.  The shell and its builtins may use the values above 125 specially to indicate specific failure modes, so the list of codes can vary between shells and operating systems (e.g., Bash uses the value 128+N as the exit status).  See: Bash - 3.7.5 Exit Status or man bash.

In general, a zero exit status indicates that a command succeeded, and a non-zero exit status indicates failure.

To check which error code is returned by the command, you can print $? for the last exit code or ${PIPESTATUS[@]} which gives a list of exit status values from a pipeline (in Bash) after a shell script exits.

There is no full list of all exit codes which can be found; however, there has been an attempt to systematize exit status numbers in kernel source.  But this is mainly intended for C/C++ programmers, and a similar standard for scripting might be appropriate.

Some list of sysexits on both Linux and BSD/OS X with preferable exit codes for programs (64-78) can be found in /usr/include/sysexits.h (or: man sysexits on BSD):

0   /* successful termination */
64  /* base value for error messages */
64  /* command line usage error */
65  /* data format error */
66  /* cannot open input */
67  /* addressee unknown */
68  /* host name unknown */
69  /* service unavailable */
70  /* internal software error */
71  /* system error (e.g., can't fork) */
72  /* critical OS file missing */
73  /* can't create (user) output file */
74  /* input/output error */
75  /* temp failure; user is invited to retry */
76  /* remote error in protocol */
77  /* permission denied */
78  /* configuration error */
/* maximum listed value */

The above list allocates previously unused exit codes from 64-78.  The range of unallocated exit codes will be further restricted in the future.

However, the above values are mainly used in sendmail and used by pretty much nobody else, so they aren't anything remotely close to a standard (as pointed out by Gilles).

In shell, the exit status values are as follows (based on Bash):

  • 1-125 - Command did not complete successfully.  Check the command's man page for the meaning of the status.  A few examples below:

  • 1 - Catchall for general errors

    Miscellaneous errors, such as "divide by zero" and other impermissible operations.

    Example:

      $ let "var1 = 1/0"; echo $?
      -bash: let: var1 = 1/0: division by 0 (error token is "0")
      1
    
  • 2 - Misuse of shell builtins (according to Bash documentation)

    Missing keyword or command, or permission problem (and diff return code on a failed binary file comparison).

    Example:

       empty_function() {}
    
  • 6 - No such device or address

    Example:

      $ curl foo; echo $?
      curl: (6) Could not resolve host: foo
      6
    
  • 124 - command times out

  • 125 - if a command itself fails (see: coreutils)

  • 126 - if command is found but cannot be invoked (e.g., is not executable)

    Permission problem or command is not an executable.

    Example:

      $ /dev/null
      $ /etc/hosts; echo $?
      -bash: /etc/hosts: Permission denied
      126
    
  • 127 - if a command cannot be found, the child process created to execute it returns that status

    Possible problem with $PATH or a typo.

    Example:

      $ foo; echo $?
      -bash: foo: command not found
      127
    
  • 128 - Invalid argument to exit

    exit takes only integer args in the range 0 - 255.

    Example:

      $ exit 3.14159
      -bash: exit: 3.14159: numeric argument required
    
  • 128-254 - fatal error signal "n" - command died due to receiving a signal. The signal code is added to 128 (128 + SIGNAL) to get the status (Linux: man 7 signal, BSD: man signal), few examples below:

  • 130 - command terminated due to Ctrl-C being pressed, 130-128=2 (SIGINT)

    Example:

      $ cat
      ^C
      $ echo $?
      130
    
  • 137 - if command is sent the KILL(9) signal (128+9), the exit status of command otherwise

    kill -9 $PPID of script.

  • 141 - SIGPIPE - write on a pipe with no reader

    Example:

      $ hexdump -n100000 /dev/urandom | tee &>/dev/null >(cat > file1.txt) >(cat > file2.txt) >(cat > file3.txt) >(cat > file4.txt) >(cat > file5.txt)
      $ find . -name '*.txt' -print0 | xargs -r0 cat | tee &>/dev/null >(head /dev/stdin > head.out) >(tail /dev/stdin > tail.out)
      xargs: cat: terminated by signal 13
      $ echo ${PIPESTATUS[@]}
      0 125 141
    
  • 143 - command terminated by signal code 15 (128+15=143)

    Example:

      $ sleep 5 && killall sleep &
      [1] 19891
      $ sleep 100; echo $?
      Terminated: 15
      143
    
  • 255* - exit status out of range.

    exit takes only integer args in the range 0 - 255.

    Example:

      $ sh -c 'exit 3.14159'; echo $?
      sh: line 0: exit: 3.14159: numeric argument required
      255
    

According to the above table, exit codes 1 - 2, 126 - 165, and 255 have special meanings, and should therefore be avoided for user-specified exit parameters.

Please note that out of range exit values can result in unexpected exit codes (e.g., exit 3809 gives an exit code of 225, because 3809 % 256 = 225).

See:

4
  • 1
    errno values are used by system APIs, they are not use as exit statuses (they aren't even in the right range) and they're irrelevant for shell scripting. Sysexits values are from sendmail and used by pretty much nobody else, they aren't anything remotely close to a standard. Sep 7, 2016 at 0:27
  • What is an exit value as stated at the end? Is it a function return value?
    – Timo
    Nov 4, 2020 at 11:57
  • the company innovationsts seems to have removed the page, this seems to be the latest archive of the linxed article: web.archive.org/web/20160926100327/http://innovationsts.com/… (among other things it mentions man 7 signal). May 30, 2023 at 13:41
  • The fact that curl returns 6 when it can't resolve a hostname is specific to it, and has nothing to do with any shell. Bash's exit seems to exit the shell with status 2 if the argument is invalid, in versions starting at Bash 4.3 (since 2014). I can see that 128 exit code only in the ancient Bash 2.0; even Bash 3.2 exits with 255. The coreutils timeout exiting with 125 if it fails is specific to it, and not to any shell. That list would be better if it made a clearer distinction between numbers used by different tools.
    – ilkkachu
    Apr 17 at 17:43
27

There is no "recipe" to get the meanings of an exit status of a given terminal command.

My first attempt would be the manpage:

user@host:~# man ls 
   Exit status:
       0      if OK,

       1      if minor problems (e.g., cannot access subdirectory),

       2      if serious trouble (e.g., cannot access command-line argument).

Second: Google. See wget as an example.

Third: The exit statuses of the shell, for example bash. Bash and it's builtins may use values above 125 specially. 127 for command not found, 126 for command not executable. For more information see the bash exit codes.

1
  • yeah some man, info, ... pages do include them.. and I was concerned with those who didn't. ..and I know a web research is always an option. ..as for now it appears it was just the bash exit codes I had to look for..
    – rusty
    Jan 22, 2014 at 9:09
6

You will have to look into the code/documentation. However the thing that comes closest to a "standardization" is errno.h

6
  • thanks for pointing the header file.. tried looking into the documentation of a few utils.. hard time finding the exit codes, seems most will be the stderrs...
    – rusty
    Jan 22, 2014 at 9:13
  • 7
    errno.h is irrelevant when it comes to exit codes, only error messages. Jan 22, 2014 at 23:41
  • Most programs return exit codes according to the BSD convention, as laid out in sysexits.h. However, some programs do return errnos, and I actually think returning errnos makes the most sense. Unhandled errnos propagate upwards, like exceptions, (the errno stays, functions return e.g., -1 or 0|NULL). Since programs are just functions, albeit functions that are run in a separate address space, it makes sense that a program might wish to continue the errno propagation across the process boundary. Jan 12, 2016 at 0:14
  • 1
    @PSkocik, do you have an example of such a command? errnos are not portable (values not consistent across systems), and there's no portable way to get the err name or message from the value (zsh has a builtin for that). Not to mention that some systems have errnos above 123 that would clash with common special-meaning error codes. Usually, commands print the messages from the errno and return a success/failure exit status. commands are intended for users. functions/system calls are intended for programmers. Sep 7, 2016 at 8:17
  • @StéphaneChazelas I've seen it a couple of times, but not in any well established programs, I have to admit. I've been personally returning errno+1 in my toy system lately ( so that 1 continues to mean "any error") because I think serializing errno's across the process boundary makes better sense than translating according to the BSD convention, as program executions are essentially function invocations, and functions use errno. I use my own last-exit-status decoder in my PROMPT_COMMAND (bash) so I get something like "($numeric_code|$bsd_decoded|$errno_plus_one_decoded)". Sep 7, 2016 at 9:00
0

As far as I know, there are only two, more-or-less, standard values -- both defined in stdlib.h for use with exit():

  • EXIT_SUCCESS (=0)
  • EXIT_FAILURE (=1)

And the only de-facto standard value, i.e., having the same meaning for all programs in the world, is 0 (zero) which stands for SUCCESS.

Different programs introduce different lists of returned "failure"-codes to distinguish or emphasize different errors (different types or severity). Some programs even use the returned value to report the integer number of discovered runtime errors (e.g., the number of failed unit-tests in the suit).

I wouldn't recommend to introduce any kind of "new standard" extending the stdlib.h

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .