Linux 中是否有任何标准的退出状态代码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1101957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:30:21  来源:igfitidea点击:

Are there any standard exit status codes in Linux?

linuxerror-handlingexit-code

提问by Nathan Fellman

A process is considered to have completed correctly in Linux if its exit status was 0.

如果进程的退出状态为 0,则认为该进程在 Linux 中已正确完成。

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.

我已经看到分段错误通常会导致退出状态为 11,尽管我不知道这只是我工作的惯例(像那样失败的应用程序都是内部的)还是标准。

Are there standard exit codes for processes in Linux?

Linux 中的进程是否有标准的退出代码?

采纳答案by ephemient

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

8 位返回码和 8 位灭杀信号数在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.

你如何确定退出状态?传统上,shell 只存储 8 位返回码,但如果进程异常终止,则设置高位。

$ 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 SIGSEGVsignal handler which then calls exitnormally, so it isn't actually getting killed by the signal. (Programs can chose to handle any signals aside from SIGKILLand SIGSTOP.)

如果您看到除此之外的任何内容,那么该程序可能有一个SIGSEGV信号处理程序,然后exit正常调用,因此它实际上并没有被信号杀死。(程序可以选择处理除SIGKILL和之外的任何信号SIGSTOP。)

回答by Amadeus45

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

当 Linux 返回 0 时,表示成功。其他任何事情都意味着失败,每个程序都有自己的退出代码,因此将它们全部列出来会很长......!

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.

关于11错误码,确实是段错误号,主要是指程序访问了一个没有分配的内存位置。

回答by segfault

'1'>>> Catchall for general errors

'1'>>> 一般错误的 Catchall

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

'2'>>> 滥用 shell 内置函数(根据 Bash 文档)

'126'>>> Command invoked cannot execute

'126'>>> 调用的命令无法执行

'127'>>>"command not found"

'127'>>>“未找到命令”

'128'>>> Invalid argument to exit

'128'>>> 无效的退出参数

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

'128+n'>>>致命错误信号“n”

'130'>>> Script terminated by Control-C

'130'>>> 脚本被 Control-C 终止

'255'>>>Exit status out of range

'255'>>>退出状态超出范围

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

这是用于 bash 的。但是,对于其他应用程序,有不同的退出代码。

回答by Chris Arguin

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

除了 0 表示成功之外,没有标准的退出代码。非零也不一定意味着失败。

stdlib.h does define EXIT_FAILUREas 1 and EXIT_SUCCESSas 0, but that's about it.

stdlib.h 确实定义EXIT_FAILURE为 1 和EXIT_SUCCESS0,但仅此而已。

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

段错误上的 11 很有趣,因为 11 是内核用于在发生段错误时终止进程的信号编号。内核或外壳程序中可能有某种机制将其转换为退出代码。

回答by Dean Povey

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.

程序返回 16 位退出代码。如果程序被信号杀死,则高位字节包含使用的信号,否则低位字节是程序员返回的退出状态。

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.

该退出代码如何分配给状态变量 $?然后是外壳。Bash 保留状态的低 7 位,然后使用 128 +(信号 nr)表示信号。

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

程序的唯一“标准”约定是成功为 0,错误为非零。使用的另一个约定是在出错时返回 errno。

回答by Dean Povey

sysexits.hhas 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.

sysexits.h有一个标准退出代码列表。它似乎至少可以追溯到 1993 年,一些像 Postfix 这样的大项目使用它,所以我想这是要走的路。

From the OpenBSD man page:

从 OpenBSD 手册页:

According to style(9), it is not good practice to call exit(3) with arbi- trary values to indicate a failure condition when ending a program. In- stead, the pre-defined 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.
根据 style(9),在结束程序时使用任意值调用 exit(3) 来指示失败条件并不是一个好习惯。相反,应该使用来自 sysexits 的预定义退出代码,这样进程的调用者可以在不查看源代码的情况下粗略估计故障类别。

回答by Daniel Schuler

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

标准 Unix 退出代码由 sysexits.h 定义,正如另一张海报所提到的。Poco 等便携式库使用相同的退出代码 - 以下是它们的列表:

http://pocoproject.org/docs/Poco.Util.Application.html#16218

http://pocoproject.org/docs/Poco.Util.Application.html#16218

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").

信号11是SIGSEGV(段违例)信号,它不同于返回码。该信号由内核在响应错误页面访问时生成,导致程序终止。信号列表可以在信号手册页中找到(运行“man signal”)。

回答by Schof

Part 1: Advanced Bash Scripting Guide

第 1 部分:高级 Bash 脚本指南

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

与往常一样,Advanced Bash Scripting Guide提供了大量信息:(这是在另一个答案中链接的,但指向非规范 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)

1:捕获一般错误
2:滥用 shell 内置函数(根据 Bash 文档)
126:调用的命令无法执行
127:“找不到命令”
128:退出参数无效
128+n:致命错误信号“n”
255:退出状态超出范围(退出只需要 0 - 255 范围内的整数参数)

Part 2: sysexits.h

第 2 部分:sysexits.h

The ABSG references sysexits.h.

ABSG 参考sysexits.h

On Linux:

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

回答by Frederick

To a first approximation, 0 is sucess, 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 sucess, there's a few other exceptions I found.

粗略估计,0 表示成功,非零表示失败,1 表示一般失败,大于 1 的任何值表示特定失败。除了 false 和 test 的微不足道的例外,它们都旨在为成功给出 1,我还发现了其他一些例外。

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

更现实地说,0 表示成功或可能失败,1 表示一般失败或可能成功,如果 1 和 0 都用于成功,则 2 表示一般失败,但也可能是成功。

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.

如果比较的文件相同,则 diff 命令给出 0,如果它们不同,则给出 1,如果二进制文件不同,则给出 2。2也意味着失败。除非您未能提供参数,否则 less 命令为失败提供 1,在这种情况下,尽管失败,它仍会退出 0。

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.

more 命令和 spell 命令为失败给出 1,除非失败是由于权限被拒绝、文件不存在或尝试读取目录造成的。在任何这些情况下,尽管失败,它们仍会退出 0。

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

然后 expr 命令给出 1 表示成功,除非输出是空字符串或零,在这种情况下,0 表示成功。2 和 3 是失败的。

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.

然后是成功或失败模棱两可的情况。当 grep 找不到模式时,它退出 1,但它退出 2 以表示真正的失败(例如权限被拒绝)。当 Klist 无法找到票证时,它也会退出 1,尽管这与 grep 未找到模式或当您 ls 一个空目录时相比,实际上并没有更多的失败。

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

因此,不幸的是,即使在非常常用的可执行文件上,Unix 的力量似乎也没有强制执行任何逻辑规则集。

回答by alexis

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

较旧的答案都没有正确描述退出状态 2。与他们声称的相反,状态 2 是您的命令行实用程序在调用不当时实际返回的内容。(是的,一个答案可能是 9 年前的,有数百个赞成票,但仍然是错误的。)

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
  • 退出状态 0:成功
  • 退出状态 1:“失败”,由程序定义
  • 退出状态2:命令行使用错误

For example, diffreturns 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 -Yor diff a b cwill all result in $?being set to 2. This is and has been the practice since the early days of Unix in the 1970s.

例如,diff如果它比较的文件相同,则返回 0,如果它们不同,则返回 1。按照长期以来的惯例,unix 程序在错误调用时返回退出状态 2(未知选项、错误数量的参数等)。例如,diff -N, grep -Yordiff a b c都将导致$?被设置为 2。自Unix 在 1970 年代的早期。

The accepted answerexplains 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.

接受的答案解释时,命令会发生什么信号终止。简而言之,由于未捕获的信号而终止会导致退出状态128+[<signal number>。例如,由SIGINT信号 2)终止会导致退出状态 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 anycommon Unix utility that returns 64 on incorrect invocation (examples welcome). Careful reading of the source codereveals that sysexits.his 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.

  1. 几个答案将退出状态 2 定义为“滥用 bash 内置函数”。这仅适用于bash(或 bash 脚本)以状态 2 退出时。将其视为不正确使用错误的特例。

  2. sysexits.h,在最流行的答案中提到,退出状态EX_USAGE(“命令行使用错误”)被定义为 64。但这并不反映现实:我不知道任何常见的 Unix 实用程序会在错误调用时返回 64(欢迎举例) )。仔细阅读源代码表明这sysexits.h是有抱负的,而不是真实用法的反映:

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

    换言之,这些定义并未反映当时(1993 年)的普遍做法,而是有意与之不相容。更可惜。