退出代码的含义(一般)
ISO/IEC 9899(编程语言:C)、ISO/IEC 9945(IEEE 1003、POSIX)
没有什么是专门为 Java / JVM 定义的。这些退出代码的含义由 ISO/IEC 9899(编程语言:C,例如 7.20.4.3ISO/IEC 9899:TC3 的 exit 函数)、ISO/IEC 9945(IEEE 1003、POSIX)和类似规范定义,以及总是这样:
shell 环境(sh、bash、cmd.exe、make 等)使用它来确定程序是成功退出(0)还是出现错误(不是 0)。
强烈建议只使用 0 表示成功。使用 0 以外的值表示成功的程序会令 shell 脚本、Makefile 等的作者头疼。
由各个程序定义不同失败值的附加语义。但是,我认为-1 并不是一个好主意。最好的办法是使用EXIT_SUCCESS 和EXIT_FAILURE,但是,<stdlib.h> 中的这些定义在 Java 中没有对应的对应项。 ISO/IEC 9899:2011 没有描述应如何定义 EXIT_FAILURE 和 EXIT_SUCCESS。但是,它将 0 定义为与 EXIT_SUCCESS 具有相同的语义,并且我不知道任何系统会执行以下操作,因此这是 Java 程序员可以假设的最好的事情:
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
因此,如果区分不同类型的失败很重要,我会使用 0 表示成功,使用 1 表示失败,并使用不同于 1 的值。一个很好的例子是grep 命令。从它的手册页(GNU grep):
退出状态
如果找到选定的行,则退出状态为 0,如果未找到,则退出状态为 1。如果发生错误,则退出状态为 2。(注意:POSIX 错误处理代码应检查“2”或更大。)
我不会使用 -1,因为它会设置所有位,并且根据环境的不同,-1 实际上可能会意外生成附加的虚假信息,例如声称发出了信号等。实际上,为了便于移植,退出代码应该在[0..127] 范围内,除非你真的很清楚自己在做什么。
例如,在大多数 POSIX 系统上,退出代码会被截断为 8 位,而 127 以上的退出代码的语义是退出是由信号引起的。
BSD
BSD 已尝试提供更多退出代码,可在/usr/include/sysexits.h (man page) 中找到。他们是这样的:
- 64:命令行使用错误
- 65:数据格式错误
- 66:无法打开输入
- 67:收件人未知
- 68:主机名未知
- 69:服务不可用
- 70:内部软件错误
- 71:系统错误(即无法分叉)
- 72:关键操作系统文件丢失
- 73:无法创建(用户)输出文件
- 74:输入/输出错误
- 75:临时故障;邀请用户重试
- 76:协议远程错误
- 77:权限被拒绝
- 78:配置错误
在没有任何其他有意义的标准的情况下,我认为我们能做的最好的事情就是使用它们。
解释 JVM 生成的退出值
POSIX 上的 JVM
在 UNIX 上,您可以通过从退出值中屏蔽低 7 位(减去 128)来获取信号,在大多数 shell 中可以使用 $? 进行查询。
-
SIGTERM -> 虚拟机:143 SIGTERM
-
SIGSEGV -> VM:134 SIGABRT(因为VM处理SIGSEGV写入hs_err文件,然后调用abort())。
与“正常”程序的比较:
JVM 没有明确指定此行为,它只是 POSIX 环境中程序的正常预期行为。即使是 SIGABRT 而不是 SIGSEGV 也或多或少是意料之中的,因为 JVM 希望自己处理 SIGSEGV,编写比普通核心文件更具体的故障转储。
Windows 上的 JVM
待办事项