Linux 中有任何标准退出状态代码吗?
- 2024-09-30 14:02:00
- admin 原创
- 94
问题描述:
如果某个进程的退出状态为 0,则认为该进程在 Linux 中已正确完成。
我发现分段错误经常会导致退出状态为 11,但我不知道这是否只是我工作的地方的惯例(像这样失败的应用程序都是内部的)或标准。
Linux 中进程有标准退出代码吗?
解决方案 1:
第一部分:高级 Bash 脚本指南
与往常一样,高级 Bash 脚本指南包含大量信息:(这链接在另一个答案中,但链接到非规范的 URL。)
1: Catchall 常见错误
2:滥用 shell 内建命令(根据 Bash 文档)
126: 调用的命令无法执行
127: “未找到命令”
128: 退出参数无效
128+n: 致命错误信号“n”
255:退出状态超出范围(退出仅接受 0 - 255 范围内的整数参数)
第 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 */
解决方案 2:
所有旧答案都没有正确描述退出状态 2。与他们声称的相反,状态 2 是命令行实用程序在被错误调用时实际返回的状态。(是的,一个答案可能已有九年历史,有数百个赞成票,但仍然是错误的。)
这是真正的、长期存在的正常终止(即不是通过信号)的退出状态约定:
退出状态 0:成功
退出状态 1:“失败”,由程序定义
退出状态 2:命令行使用错误
例如,diff
如果比较的文件相同,则返回 0,如果不同,则返回 1。按照长期惯例,unix 程序在调用不正确(未知选项、参数数量错误等)时返回退出状态 2。 例如,、diff -N
或grep -Y
都diff a b c
将导致$?
设置为 2。自 20 世纪 70 年代早期的 Unix 以来,一直都是这样做的。
可接受的答案解释了当命令被信号终止时会发生什么。简而言之,由于未捕获的信号而终止会导致退出状态128+[<signal number>
。例如,由SIGINT
(信号 2 ) 终止会导致退出状态 130。
笔记
有几个答案将退出状态 2 定义为“滥用 bash 内置命令”。这仅适用于bash(或 bash 脚本)以状态 2 退出的情况。请将其视为错误使用的特殊情况。
在最受欢迎的答案
sysexits.h
中提到,退出状态(“命令行使用错误”)定义为 64。但这并不反映现实:我不知道有任何常见的 Unix 实用程序在调用不正确时返回 64(欢迎提供示例)。仔细阅读源代码会发现,这只是一种期望,而不是真实用法的反映:EX_USAGE
`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 年)的普遍做法,而是故意与之不相容。更令人遗憾。
解决方案 3:
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
", 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
", WTERMSIG(status));
/* prints: "second child died with 11" */
}
您如何确定退出状态?传统上,shell 仅存储 8 位返回代码,但如果进程异常终止,则会设置高位。
$ sh -c'退出 42';回显 $?
四十二
$ sh -c'kill -SEGV $$';回显$?
分段错误
139
$ 表达式 139 - 128
11
如果您看到的不是这个,那么程序可能有一个SIGSEGV
信号处理程序,然后exit
正常调用,因此它实际上并没有被信号杀死。(程序可以选择处理除SIGKILL
和 之外的任何信号SIGSTOP
。)
解决方案 4:
‘1’:捕获所有一般错误
‘2’:滥用 shell 内置命令(根据 Bash 文档)
‘126’:调用的命令无法执行
‘127’:“未找到命令”
‘128’:退出参数无效
‘128+n’:致命错误信号“n”
‘130’Ctrl
:脚本以+终止C
‘255’:退出状态超出范围
这是针对 Bash 的。但是,对于其他应用程序,有不同的退出代码。
解决方案 5:
除了 0 表示成功之外,没有标准退出代码。非零也不一定意味着失败。
头文件stdlib.h确实定义EXIT_FAILURE
为 1 和EXIT_SUCCESS
0,但仅此而已。
分段错误中的 11很有趣,因为 11 是内核在发生分段错误时用来终止进程的信号编号。内核或 shell 中可能存在某种机制,将其转换为退出代码。
解决方案 6:
头文件sysexits.h有一个标准退出代码列表。它似乎至少可以追溯到 1993 年,一些大型项目(如Postfix))都在使用它,所以我想这是可行的方法。
来自OpenBSD手册页:
根据 style(9),在结束程序时使用任意值调用 exit(3) 来指示失败情况并不是一个好习惯。相反,应该使用 sysexits 中的预定义退出代码,这样进程的调用者就可以粗略估计失败类别,而无需查找源代码。
解决方案 7:
大致来说,0 表示成功,非零表示失败,1 表示一般失败,任何大于 1 的数都表示特定失败。除了 false 和 test 这两个微不足道的例外情况(它们都旨在将 1 表示成功)之外,我还发现了其他一些例外情况。
更现实地说,0 表示成功或可能失败,1 表示一般失败或可能成功,如果 1 和 0 都用于表示成功,则 2 表示一般失败,但也可能成功。
如果比较的文件相同,diff命令会给出 0;如果不同,则给出 1;如果二进制文件不同,则给出 2。2 也表示失败。less命令)会给出 1 表示失败,除非您未能提供参数,在这种情况下,尽管失败,它仍会退出 0。
more)命令和spell 命令在失败时返回 1,除非失败是由于权限被拒绝、文件不存在或尝试读取目录。在任何这些情况下,它们都会退出 0,尽管失败了。
然后,expr命令会返回 1 表示成功,除非输出是空字符串或零,在这种情况下,0 表示成功。2 和 3 表示失败。
然后,有些情况是成功或失败不明确。当grep无法找到模式时,它会退出 1,但如果出现真正的失败(如权限被拒绝),它会退出 2。当klist无法找到票证时,它也会退出 1,尽管这实际上并不比grep找不到模式或 ls 空目录时更严重。
因此,不幸的是,Unix 的权力似乎并没有强制执行任何逻辑规则,即使是在非常常用的可执行文件上也是如此。
解决方案 8:
程序返回一个 16 位的退出代码。如果程序被信号终止,则高位字节包含所使用的信号,否则低位字节是程序员返回的退出状态。
然后,如何将退出代码分配给状态变量 $? 取决于 shell。Bash 保留状态的低 7 位,然后使用 128 + (信号编号) 来指示信号。
程序的唯一“标准”约定是 0 表示成功,非零表示错误。另一个约定是在发生错误时返回 errno。
解决方案 9:
正如David 提到的那样,标准 Unix 退出代码由 sysexits.h 定义。可移植库(例如 Poco)使用相同的退出代码 - 以下是它们的列表:
类 Poco::Util::Application,ExitCode
信号 11 是 SIGSEGV(段违规)信号,它与返回代码不同。此信号由内核生成,用于响应错误的页面访问,这会导致程序终止。信号列表可在信号手册页中找到(运行“ man signal ”)。
解决方案 10:
有些是惯例,但其他一些保留的则是 POSIX 标准的一部分。
126 —— 找到了要执行的文件,但它不是可执行实用程序。
127 —— 未找到要执行的实用程序。
128——命令被信号中断。
请参阅的“理由”部分man 1p exit
。
解决方案 11:
当 Linux 返回 0 时,表示成功。其他任何值都表示失败。每个程序都有自己的退出代码,因此将它们全部列出会很长...!
关于 11 错误代码,它确实是段错误号,主要意味着程序访问了未分配的内存位置。
解决方案 12:
您可以查看以下 Linux Shell 脚本的常见退出代码列表。下面附有更多信息的链接:希望这可以帮助某人快速调试。
0 Success
1 Operation not permitted
2 No such file or directory
3 No such process
4 Interrupted sys
5 Input/output error
6 No such device or address
7 Argument list too long
8 Exec format error
9 Bad file descriptor
10 No child processes
11 Resource temporarily unavailable
12 Cannot allocate memory
13 Permission denied
14 Bad address
15 Block device required
16 Device or resource busy
17 File exists
18 Invalid cross-device link
19 No such device
20 Not a directory
21 Is a directory
22 Invalid argument
23 Too many open files in system
24 Too many open files
25 Inappropriate ioctl for device
26 Text file busy
27 File too large
28 No space left on device
29 Illegal seek
30 Read-only file system
31 Too many links
32 Broken pipe
33 Numerical argument out of domain
34 Numerical result out of range
35 Resource deadlock avoided
36 File name too long
37 No locks available
38 Function not implemented
39 Directory not empty
40 Too many levels of symbolic links
42 No message of desired type
43 Identifier removed
44 Channel number out of range
45 Level 2 not synchronized
46 Level 3 halted
47 Level 3 reset
48 Link number out of range
49 Protocol driver not attached
50 No CSI structure available
51 Level 2 halted
52 Invalid exchange
53 Invalid request descriptor
54 Exchange full
55 No anode
56 Invalid request code
57 Invalid slot
59 Bad font file format
60 Device not a stream
61 No data available
62 Timer expired
63 Out of streams resources
64 Machine is not on the network
65 Package not installed
66 Object is remote
67 Link has been severed
68 Advertise error
69 Srmount error
70 Communication error on send
71 Protocol error
72 Multihop attempted
73 RFS specific error
74 Bad message
75 Value too large for defined data type
76 Name not unique on network
77 File descriptor in bad state
78 Remote address changed
79 Can not access a needed shared library
80 Accessing a corrupted shared library
81 .lib section in a.out corrupted
82 Attempting to link in too many shared libraries
83 Cannot exec a shared library directly
84 Invalid or incomplete multibyte or wide character
85 Interrupted system call should be restarted
86 Streams pipe error
87 Too many users
88 Socket operation on non-socket
89 Destination address required
90 Message too long
91 Protocol wrong type for socket
92 Protocol not available
93 Protocol not supported
94 Socket type not supported
95 Operation not supported
96 Protocol family not supported
97 Address family not supported by protocol
98 Address already in use
99 Cannot assign requested address
100 Network is down
101 Network is unreachable
102 Network dropped connection on reset
103 Software caused connection abort
104 Connection reset by peer
105 No buffer space available
106 Transport endpoint is already connected
107 Transport endpoint is not connected
108 Cannot send after transport endpoint shutdown
109 Too many references
110 Connection timed out
111 Connection refused
112 Host is down
113 No route to host
114 Operation already in progress
115 Operation now in progress
116 Stale file handle
117 Structure needs cleaning
118 Not a XENIX named type file
119 No XENIX semaphores available
120 Is a named type file
121 Remote I/O error
122 Disk quota exceeded
123 No medium found
125 Operation canceled
126 Required key not available
127 Key has expired
128 Key has been revoked
129 Key was rejected by service
130 Owner died
131 State not recoverable
132 Operation not possible due to RF-kill
133 Memory page has hardware error
https://www.cyberciti.biz/faq/linux-bash-exit-status-set-exit-statusin-bash/
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件