我已经看到,分段错误通常会导致退出状态为11,尽管我不知道这是否是只是我工作的惯例(失败的应用程序全部是内部的)或标准。
Linux中是否有用于进程的标准退出代码?
#1 楼
从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" */
}
如何确定退出状态?传统上,外壳程序仅存储8位返回码,但是如果进程异常终止,则会设置高位。
这样,程序可能会有一个
SIGSEGV
信号处理程序,该信号处理程序随后会正常调用exit
,因此它实际上并没有被信号杀死。 (程序可以选择处理SIGKILL
和SIGSTOP
之外的任何信号。)评论
考虑到问题出现的方式,这似乎不是最有用(因此也被接受)的答案。
– David J.
2013年12月9日在22:49
#2 楼
第1部分:高级Bash脚本指南和往常一样,《高级Bash脚本指南》具有重要信息:
(这是另一个答案中的链接,但链接到非规范的URL。) />
1:常见错误的Catchall2:滥用shell内置函数(根据Bash文档)126:调用的命令无法执行127:“找不到命令” 128:退出参数无效128 + n:致命错误信号“ n” 255:退出状态超出范围(退出仅接受0-255范围内的整数args)
第2部分:sysexits.h
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 */
评论
请注意,在某些类型的Unix中,某些命令使用退出状态2表示其他情况。例如,许多grep实现使用退出状态2表示错误,使用退出状态1表示未找到选定的行。
– NamshubWriter
2012年10月25日17:06
在BSD上,有一个手册页,汇总了sysexits.h中的信息:man sysexits
–georgebrock
13年7月29日在9:38
@NamshubWriter说了什么。退出状态2是在Unix实用程序中不正确使用命令行的通用方法,不仅是“某些类型的unix”,而且通常也是这样。此答案中显示的标题现在或1987年编写时均未反映实际约定。
–alexis
17年5月8日在9:16
ABS不是“伟大的”。请仔细阅读该主题;很难找到批评。
–tripleee
19年11月30日在9:05
但是sysexits.h的实际官方源代码在哪里?大家一直引用的手册页只是散文。例如,它引用EX_OK,但实际上并没有像其他代码那样以规范的方式定义它。还有更多缺少的东西吗?
– Garret Wilson
19年12月11日下午16:31
#3 楼
'1'>>>常见错误的所有内容'2'>>>滥用shell内置函数(根据Bash文档)
'126'>>>调用了命令无法执行
'127'>>>“找不到命令”
'128'>>>退出参数无效
'128+ n'>>>致命错误信号“ n”
'130'>>>脚本被Control-C终止
'255'>>>退出状态超出范围
这是bash专用。但是,对于其他应用程序,存在不同的退出代码。
评论
看起来你们俩都在同一分钟内回答了。 Tian必须很快就能看到您的链接并将其粘贴。
–内森·费尔曼(Nathan Fellman)
2009年7月9日下午5:37
注意,“控制C的输出130”与信号n的“ 128 + n”一致; control-C生成信号2的SIGINT。
–乔纳森·莱弗勒(Jonathan Leffler)
2011年9月3日在18:44
这似乎是从ABS抄袭而来的,但没有注明出处。 (我们可以知道,因为ABS包含不正确或至少具有误导性的信息。)
–tripleee
16-10-10在8:43
根据高级Bash脚本指南,这些是保留的退出代码。因此,对于用户指定的退出参数,应避免使用这些值。
–在这里
17年1月9日在20:14
#4 楼
较早的答案均未正确描述退出状态2。与他们声称的相反,状态2是您的命令行实用程序在不正确调用时实际返回的内容。 (是的,答案可能是9岁,有数百次投票,但仍然是错误的。)这是正常终止的真实,长期存在的退出状态约定,即不是通过信号:
退出状态0:成功
退出状态1:“失败”,由程序定义
退出状态2:命令行使用错误
例如,如果
diff
比较的文件相同,则返回0,如果它们不同则返回1。按照长期的惯例,unix程序在错误调用(未知选项,错误的参数数量等)时会返回退出状态2,例如,diff -N
,grep -Y
或diff a b c
都将导致$?
设置为2。 从1970年代Unix早期开始就采用这种做法。
公认的答案解释了当命令被信号终止时会发生什么。简而言之,由于未捕获的信号导致的终止导致退出状态
128+[<signal number>
。例如,通过SIGINT
(信号2)终止会导致退出状态130。注意事项
多个答案将退出状态2定义为“滥用bash内置函数”。这仅在bash(或bash脚本)以状态2退出时适用。将其视为错误使用错误的特殊情况。行使用错误“)定义为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 other exit statuses that random programs may
* already return.
换句话说,这些定义并不反映当时(1993年)的通用做法,但故意与之不符。更可惜。
评论
程序通过捕获SIGINT / Ctrl-C处理终止时应返回什么?还是130?除了bash之外,其他外壳的使用也很重要吗?
– Gringo Suave
18年7月20日在17:50
执行程序的外壳无关紧要;理论上,一个进程可以根据其父进程选择以不同的状态退出,但是我从未听说过发生这种情况的情况。
–alexis
18年7月24日在14:22
如果某个程序捕获了SIGINT,进行清理并退出,则该状态对于该程序有意义。例如,more将重置终端模式并以状态0退出(您可以尝试)。
–alexis
18年7月24日在14:23
这个答案意味着比实际情况高得多的标准化等级。值2的含义没有适当的标准化,因此可以预见的是实际的做法非常复杂。的确,许多工具针对不正确的使用会返回2,但是“不正确的使用”的含义还不是很明确,还有许多其他工具没有遵守该约定。
–tripleee
19年11月30日在9:02
@tripleee“工具”也没有很好的定义! :-)当然,任何人都可以编写命令行程序,并且可以返回任何内容,但是老式的“ Unix命令行实用程序”比Linux或GNU coreutils的内容要长得多对此保持一致。如果您有其他看法,请在此组中命名一些不使用状态2的工具。同样,“不当使用”是您的用语(我同意这是一个模糊的用语);我写了“命令行使用错误”,它非常具体:不存在或不兼容的选项,错误数量的非选项参数,等等。
–alexis
19/12/3在21:07
#5 楼
除了0表示成功,没有标准的退出代码。非零也不一定意味着失败。stdlib.h确实将
EXIT_FAILURE
定义为1并将EXIT_SUCCESS
定义为0,但这就是关于它的内容。有趣的是,当出现段错误时,内核用来终止进程的信号号为11。内核或外壳中可能存在某种机制,可以将其转换为退出代码。#6 楼
sysexits.h包含标准退出代码的列表。它似乎至少可以追溯到1993年,并且一些大型项目(如Postfix)都在使用它,所以我想这就是要走的路。 br />根据style(9),在结束程序时,用arbi-trary值调用exit(3)指示失败情况不是一个好习惯。相反,应该使用sysexits的预定义退出代码,因此,该过程的调用者可以在不查找源代码的情况下大致了解故障类别
。
#7 楼
初步近似,成功为0,非零为失败,其中1为一般性失败,大于1的任何为特定失败。除了虚假和测试这两个平凡的异常(都旨在为成功赋予1)之外,我还发现了其他一些异常。更现实地,0表示成功或失败,1表示一般失败或可能成功,如果1和0都用于成功,则2表示一般失败,但也可能成功。
如果比较的文件相同,则diff命令给出0,如果它们不同则给出1,如果二进制文件不同则给出2。 2也表示失败。 less命令为失败提供1,除非您不提供参数,否则即使失败也会退出0。
more命令和spell命令为失败提供1,除非失败是权限被拒绝,文件不存在或尝试读取目录的结果。在上述任何一种情况下,即使失败,它们也会退出0。 2和3都是失败。
然后在某些情况下,成功或失败是模棱两可的。当grep找不到模式时,它退出1,但是由于真正的失败(例如,权限被拒绝)而退出2。当找不到票证时,Klist也会退出1,尽管与grep找不到模式或当您创建一个空目录时相比,这实际上并不是更多的失败。 ,不幸的是,即使在非常常用的可执行文件上,unix的功能似乎也不强制执行任何逻辑规则。
评论
我也要指出diff的行为。 wget也有详细的错误(例如6个身份验证失败),但随后它们使用1 =通用错误,2..n =特定错误
–PypeBros
16年8月30日在10:25
#8 楼
程序返回16位退出代码。如果程序被信号杀死,则高位字节包含所使用的信号,否则低位字节是程序员返回的退出状态。该退出代码如何分配给状态变量$?然后由外壳决定。 Bash保留状态的低7位,然后使用128 +(信号nr)表示信号。
程序的唯一“标准”约定是0表示成功,非零表示错误。使用的另一种约定是在出错时返回errno。
#9 楼
标准的Unix退出代码由sysexits.h定义,正如另一个提及的内容。便携式库(例如Poco)使用相同的退出代码-这是它们的列表: //pocoproject.org/docs/Poco.Util.Application.html#16218
信号11是SIGSEGV(段违规)信号,与返回码不同。该信号由内核响应于错误的页面访问而生成,这导致程序终止。信号列表可以在信号手册页中找到(运行“ man signal”)。
#10 楼
当Linux返回0时,表示成功。别的意思就是失败,每个程序都有自己的退出代码,因此将它们全部列出会很长...!关于11个错误代码,它的确是分段错误号,主要是指程序访问了未分配的内存位置。
评论
它始终为11,因为内核会杀死它并分配“退出值”。同样,其他类型的故障将始终获得相同的退出值。
– Alex Gartrell
09年7月9日在6:04
评论
如果要查找系统功能返回的“系统错误号”,请查看errno