如果在Linux中进程的退出状态为0,则认为该进程已经正确完成。
我发现,分段错误常常会导致退出状态为11,但我不知道这是否只是我们公司的惯例(所有失败的应用程序都是内部的),还是一个标准。
在Linux中,进程的退出码是否有标准化的规定?
如果在Linux中进程的退出状态为0,则认为该进程已经正确完成。
我发现,分段错误常常会导致退出状态为11,但我不知道这是否只是我们公司的惯例(所有失败的应用程序都是内部的),还是一个标准。
在Linux中,进程的退出码是否有标准化的规定?
和往常一样,高级Bash脚本指南有很棒的信息: (这个链接在另一个答案中提到过,但是链接不是官方的。)
1:一般错误
2:使用了shell内置命令(根据Bash文档)
126:无法执行调用的命令
127:"命令未找到"
128:退出时参数无效
128+n:致命错误信号“n”
255:退出状态超出范围(exit只接受0-255之间的整数参数)
ABSG引用了sysexits.h
。
在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 */
man sysexits
。 - georgebrocksysexits.h
的实际官方源代码在哪里呢?每个人都参考的man页面只是散文。例如,它引用了 EX_OK
,但并没有像其他代码那样规范地定义它。是否还有其他缺失的代码? - Garret Wilsonwait(2)
和相关函数的返回值中,终止进程的信号编号和返回码(exit code)会被混合在一个8位字节中。
#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" */
}
你是如何确定退出状态的?传统上,Shell 只存储 8 位返回码,但如果进程异常终止,则设置高位。如果您看到的不是这样的结果,则可能程序有SIGSEGV信号处理程序,该处理程序然后正常调用退出函数(exit),因此它实际上并没有被信号杀死。(除了SIGKILL和SIGSTOP信号外,程序可以选择处理任何信号。)之前的回答没有正确描述退出状态2。与其所声称的相反,当命令行工具被错误调用时,状态2实际上是返回的内容。(是的,一个回答可能有九年历史,拥有数百个赞,但仍然是错的。)
这里是正常终止(即非信号终止)的真正、长期存在的退出状态约定:
例如,如果比较文件并且它们相同,则diff
返回0;如果它们不同,则返回1。按照长期惯例,Unix程序在被错误调用(未知选项、错误数量的参数等)时返回退出状态2。例如,diff -N
、grep -Y
或diff a b c
都会导致$?
设置为2。这是自20世纪70年代Unix早期以来一直实践的做法。
被接受的答案解释了当命令由信号终止时会发生什么。简而言之,因未捕获信号而终止导致退出状态为128+[<signal number>
。例如,由SIGINT
(信号2)终止会导致退出状态为130。
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.
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 other 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.
more
会重置终端模式并以状态0退出(您可以尝试一下)。 - alexismkdir --xyz
、mv --xyz
和cp --xyz
都返回退出码1。另一方面,bash --xyz
和cd --xyz
返回退出码2。 - rrrrrrrrrrrrrrrr'1': 通用错误的捕获
'2': 使用了shell内置命令(根据Bash文档)
'126': 无法执行调用的命令
'127': “找不到命令”
'128': 退出操作的参数无效
'128+n': 致命错误信号“n”
'130': 脚本被Ctrl + C终止
'255': 退出状态超出范围
这适用于Bash。然而,对于其他应用程序,有不同的退出代码。
除了0表示成功之外,没有标准的退出代码,非零并不一定意味着失败。
头文件stdlib.h确实将EXIT_FAILURE
定义为1,EXIT_SUCCESS
定义为0,但仅此而已。
在段错误中的11很有趣,因为11是内核在发生段错误时用于终止进程的信号编号。可能有一些机制,无论是在内核还是在 shell 中,将其转换为退出代码。
wait(2)
的man页面列出了用于解码退出状态的宏,头文件sysexits.h
除了0
和1
之外还标准化了其他整数常量。 - ruief就近似而言,0表示成功,非零表示失败,1表示一般性的失败,大于1则表示特定的失败。除了false和test这两个显然设计为成功返回1之外,我还发现了几个其他的例外。
更实际地说,0意味着成功或者可能是失败,1意味着一般性的失败或者可能是成功,2意味着如果0和1都用于表示成功,则表示一般性的失败,但同时也可能表示成功。
diff命令比较文件后,如果相同则返回0,不同则返回1,二进制文件不同则返回2。2也表示失败。less命令在没有提供参数的情况下返回0,即使运行失败,否则将返回1。 more命令和spell命令返回1表示失败,除非失败是因为权限被拒绝、文件不存在或试图读取目录。在任何这些情况下,它们将尽管失败但退出0。最后,expr命令返回1表示成功,除非输出为空字符串或零,在这种情况下,0表示成功。2和3表示失败。
还有一些成功或失败不明确的情况。当 grep 无法找到模式时,它会退出1,但对于真正的失败(如权限被拒绝),它会退出2。当 klist 无法找到票证时,也会退出1,尽管这并不比 grep 无法找到模式或您ls一个空目录时更加失败。
因此,不幸的是,Unix的权威人士似乎没有强制执行任何逻辑规则,即使在非常常用的可执行文件上也是如此。
标准Unix退出代码由sysexits.h定义,如David提到的。 这些相同的退出代码被可移植库(如Poco)使用 - 这是它们的列表:
Poco :: Util :: Application类,ExitCode
信号11是SIGSEGV(段错误)信号,与返回代码不同。该信号由内核响应错误页面访问而生成,导致程序终止。信号列表可以在信号手册中找到(运行“man signal”)。
有些是约定,但一些其他保留的内容是POSIX标准的一部分。
126 -- 找到要执行的文件,但它不是可执行实用程序。
127 -- 未找到要执行的实用程序。
>128 -- 命令被信号中断。
请参阅 man 1p exit
的 RATIONALE 部分。