如果进程退出状态为0,则认为该进程已在Linux中正确完成。
我已经看到分段错误经常导致退出状态为11,但我不知道这是否只是我工作的惯例(那些失败的应用程序都是内部的)或标准。
Linux中的进程是否有标准退出代码?
答案 0 :(得分:327)
与往常一样,Advanced Bash Scripting Guide有great information: (这是另一个答案,但与非规范网址相关联。)
1:导致一般错误的问题 2:滥用shell内置版(根据Bash文档)
126:调用的命令无法执行
127:“未找到命令”
128:退出的参数无效
128 + n:致命错误信号“n”
255:退出状态超出范围(退出只接受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 */
答案 1 :(得分:83)
从wait(2)
& co.返回时,8位返回码和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位返回码,但如果进程异常终止则设置高位。
$ sh -c 'exit 42'; echo $? 42 $ sh -c 'kill -SEGV $$'; echo $? Segmentation fault 139 $ expr 139 - 128 11
如果你看到的不是这个,那么程序可能有一个SIGSEGV
信号处理程序然后正常调用exit
,所以它实际上并没有被信号杀死。 (除SIGKILL
和SIGSTOP
之外,程序可以选择处理任何信号。)
答案 2 :(得分:70)
'1'&gt;&gt;&gt;笼罩一般错误
'2'&gt;&gt;&gt;滥用shell内置(根据Bash文档)
<强> '126'强>&GT;&GT;&GT;调用的命令无法执行
'127'&gt;&gt;&gt;“找不到命令”
<强> '128'强>&GT;&GT;&GT;退出
的参数无效'128 + n'&gt;&gt;&gt;致命错误信号“n”
<强> '130'强>&GT;&GT;&GT;脚本由Control-C终止
'255'&gt;&gt;&gt;退出状态超出范围
这是针对bash的。但是,对于其他应用程序,有不同的退出代码。
答案 3 :(得分:47)
没有一个较旧的答案正确描述退出状态2。与他们声称的相反,状态2是您的命令行实用程序在被错误调用时实际返回的内容。(是的,答案可能是9年,有数百个upvotes,但仍然是错误的。)< / p>
以下是正常终止的真实,长期退出状态约定,即不通过信号:
例如,如果它比较的文件相同,则diff
返回0,如果它们不同则返回1。通过长期约定,unix程序在被错误调用时返回退出状态2(未知选项,错误数量的参数等)例如,diff -N
,grep -Y
或{ {1}}都会导致diff a b c
被设置为2.这是自20世纪70年代Unix早期以来的惯例。
accepted answer解释了当命令被信号终止时会发生什么。简而言之,由于未被捕获的信号导致的终止导致退出状态$?
。例如,128+[<signal number>
(signal 2)终止会导致退出状态130.
有几个答案将退出状态2定义为&#34;滥用bash builtins&#34;。仅当 bash (或bash脚本)以状态2退出时才适用。请考虑使用错误的特殊情况。
在sysexits.h
中提到的most popular answer中,退出状态SIGINT
(&#34;命令行使用错误&#34;)被定义为64.但是这并不反映现实:我不知道任何常见的Unix实用程序在错误调用时返回64(欢迎示例)。仔细阅读source code表明EX_USAGE
是有抱负的,而不是真实用法的反映:
sysexits.h
换句话说,这些定义并不反映当时(1993年)的惯常做法,而是故意与之不相容。更多可惜。
答案 4 :(得分:23)
没有标准的退出代码,除了0意味着成功。非零并不一定意味着失败。
stdlib.h确实将EXIT_FAILURE
定义为1,将EXIT_SUCCESS
定义为0,但这就是它。
关于段错误的11很有意思,因为11是内核在发生段错误时用来杀死进程的信号编号。在内核或shell中可能存在一些机制,将其转换为退出代码。
答案 5 :(得分:20)
sysexits.h 有一个标准退出代码列表。它似乎可以追溯到至少1993年,一些像Postfix这样的大项目使用它,所以我想它是要走的路。
从OpenBSD手册页:
根据风格(9),用arbi-调用exit(3)是不好的做法。 trary值表示结束程序时的失败条件。在- 相反,应该使用来自sysexits的预定义退出代码,所以 该过程的调用者可以对失败类进行粗略估计 没有查找源代码。
答案 6 :(得分:8)
对于第一个近似值,0表示成功,非零表示失败,1表示一般故障,大于1表示特定故障。除了虚假和测试的微不足道的例外,这两个例外都是为了让成功1,我发现还有一些其他的例外。
更现实地,0表示成功或可能失败,1表示一般失败或可能成功,2表示一般失败,如果1和0都用于成功,但也可能成功。
如果比较的文件相同,则diff命令给出0,如果它们不同则为1,如果二进制文件不同则为2。 2也意味着失败。 less命令为失败提供1,除非你没有提供参数,在这种情况下,尽管失败,它仍会退出0。
more命令和spell命令为失败提供1,除非失败是由于权限被拒绝,不存在的文件或尝试读取目录。在任何一种情况下,尽管失败,它们都会退出。
然后expr命令为sucess提供1,除非输出是空字符串或零,在这种情况下,0是成功的。 2和3都是失败的。
然后有成功或失败模糊的情况。当grep找不到模式时,它会退出1,但它会退出2以获得真正的失败(如权限被拒绝)。当Klist找不到票时,Klist也会退出1,尽管这不是故障,而是当grep找不到模式时,或者当你找到一个空目录时。
所以,不幸的是,即使在非常常用的可执行文件中,unix也似乎没有强制执行任何逻辑规则集。
答案 7 :(得分:5)
程序返回16位退出代码。如果程序被信号杀死,则高位字节包含所使用的信号,否则低位字节是程序员返回的退出状态。
如何将退出代码分配给状态变量$?然后是shell。 Bash保持状态的低7位,然后使用128 +(信号nr)来指示信号。
程序的唯一“标准”约定是0表示成功,非零表示错误。使用的另一个约定是在出错时返回errno。
答案 8 :(得分:3)
标准Unix退出代码由sysexits.h定义,如另一张海报所述。 便携式库(如Poco)使用相同的退出代码 - 这是一个列表:
http://pocoproject.org/docs/Poco.Util.Application.html#16218
信号11是SIGSEGV(段违规)信号,其与返回码不同。该信号由内核响应坏页面访问而生成,这导致程序终止。可以在信号手册页中找到信号列表(运行“man signal”)。
答案 9 :(得分:2)
当Linux返回0时,表示成功。其他任何东西都意味着失败,每个程序都有自己的退出代码,所以列出它们的时间很长......!
关于11错误代码,它确实是分段错误号,主要意味着程序访问了未分配的内存位置。