Linux中以下退出代码的最小值和最大值是什么:
- 从二进制可执行文件(例如:C程序)返回的退出代码。
- 从bash脚本返回的退出代码(调用时
exit
)。 - 从函数返回的退出代码(调用时
return
)。我认为这是介于0
和之间255
。
bash
外壳程序的限制。其他一些shell zsh
可以像这样返回任何带符号的32位值exit
。有些人喜欢rc
或es
可以返回他们支持的任何类型的数据(标量或列表)。有关详细信息,请参见链接的问答。
Linux中以下退出代码的最小值和最大值是什么:
exit
)。return
)。我认为这是介于0
和之间255
。bash
外壳程序的限制。其他一些shell zsh
可以像这样返回任何带符号的32位值exit
。有些人喜欢rc
或es
可以返回他们支持的任何类型的数据(标量或列表)。有关详细信息,请参见链接的问答。
Answers:
传递给_exit()
/ exit_group()
系统调用的数字(有时称为退出代码,以避免与退出状态产生歧义,这也指的是退出代码或信号号的编码以及其他信息,具体取决于进程是被终止还是正常退出)是类型的int
,因此在类似Unix的系统(例如Linux)上,通常是32位整数,其值从-2147483648(-2 31)到2147483647(2 31 -1)。
然而,在所有系统上,当父进程(或子subreaper或者init
如果父去世)使用wait()
,waitpid()
,wait3()
,wait4()
系统调用来检索它,只有它的低8位可(值从0到255(2 8 - 1))。
当使用waitid()
API(或SIGCHLD上的信号处理程序)时,在大多数系统上(以及POSIX现在在该标准的2016版中更明确地要求(请参阅_exit()
规范)),可以使用完整编号(在si_status
返回结构的字段中) )。在Linux上不是这种情况,尽管它也会通过waitid()
API 将数字截断为8位,但是将来可能会改变。
通常,您只想使用0(通常表示成功)到125,因为许多shell $?
在退出状态表示中使用大于128的值来编码被杀死进程的信号号,对于特殊情况则使用126和127。条件。
您可能希望使用126到255 exit()
表示与外壳相同的含义$?
(例如脚本执行时ret=$?; ...; exit "$ret"
)。使用0-> 255以外的值通常没有用。通常,仅当您知道父级将waitid()
在不会截断的系统上使用API并且碰巧需要32位值范围时,才这样做。请注意,exit(2048)
例如,如果您这样做,那么使用传统wait*()
API的父母将认为这是成功的。
有关更多信息,请访问:
该问答将有望回答您的其他大多数问题,并阐明退出状态的含义。我还要添加一些内容:
除非进程被杀死或调用_exit()
/ exit_group()
系统调用,否则它无法终止。从main()
in中返回时C
,libc会使用返回值调用该系统调用。
大多数语言都有exit()
包装该系统调用的函数,并且它们所取的值(如果有)通常按原样传递给系统调用。(请注意,这些通常会做更多的事情,例如由C的exit()
函数完成的清理工作,这些函数会刷新stdio缓冲区,运行atexit()
钩子...)
至少是这种情况:
$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234) = ?
$ strace -e exit_group perl -e 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234) = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234) = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)
当您使用0-255以外的值时,您偶尔会看到一些抱怨:
$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1) = ?
当您使用负值时,一些shell会抱怨:
$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2) = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: `-1234' is not a valid integer
exit_group(2) = ?
如果传递给exit
特殊内置函数的值在0-> 255之外,则POSIX会使行为未定义。
如果这样做,某些外壳会显示一些意外行为:
bash
(mksh
但不是pdksh
基于它)基于自身将值截断为8位:
$ strace -e exit_group bash -c 'exit 1234'
exit_group(210) = ?
因此,在那些shell中,如果您确实想使用0-255之外的值退出,则必须执行以下操作:
exec zsh -c 'exit -- -12345'
exec perl -e 'exit(-12345)'
那就是在同一过程中执行另一个命令,该命令可以使用所需的值调用系统调用。
如在其他问答中所提到的,ksh93
对于退出值从257到256 + max_signal_number而言,行为最奇怪exit_group()
。
$ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
zsh: suspended (signal) ksh -c 'exit "$((256 + $(kill -l STOP)))"'
否则将数字截断为bash
/ mksh
。
¹不过,在下一个版本中,这种情况可能会改变。现在,ksh93
AT&T已将开发工作作为社区的工作来接管,尽管POSIX以某种方式鼓励了该行为,
si_status
Linux中实现完整退出代码的讨论吗?
int
至少为16位,但是POSIX或多或少要求它至少为32位,并且编程环境必须具有uint32_t。我不知道Linux是否支持ints除了32bits之外的任何编程环境,我从来没有遇到过。
最小值为0
,这被视为成功值。其他所有的都是失败的。最大值255
也称为-1
。
这些规则适用于脚本和其他可执行文件以及外壳函数。
较大的值将得出256模。
bash
或在其他最常用的exit
shell中),传递给内置函数的退出代码不会被视为modulo-256,而是会导致错误。(例如,公用exit -1
程序实际上不是exit 255
大多数外壳程序中的便携式产品)。而无论是exit(-1)
在C级相当于exit(255)
是一个细节,那就是事实上的某些工作,但依赖于实现定义的行为(虽然这不是现代系统的一个问题,你很可能会利用在实践中)。
exit(1)
参数限制为8位。
这看起来很简单,但是麻烦了。
C语言(以及紧随其后的大多数其他语言,都是直接或间接的)要求从返回main
等同于exit
使用与返回值相同的参数进行调用。这是一个整数(返回类型非常清楚int
),因此原则上范围是INT_MIN
to INT_MAX
。
但是,POSIX指出,只有传递给它的最低8位才exit
可供等待的父进程使用,字面上就好像是“ status&0xFF”。
因此,实际上,退出代码是一个(仍带符号的)整数,仅设置最低的8位。
因此,最小值将为-128,最大值为127。等一下,那是不对的。从0到255。
但是,a ,当然不能这么简单。实际上,Linux(或更确切地说是bash)的做法有所不同。返回码的有效范围是0到255(即无符号)。
为了避免混淆,为了安全起见,最好假设返回代码是未签名的,然后将所有返回的内容转换wait
为未签名。这样,它便与您在Shell中看到的一致。由于清除了最高位(包括最高有效位),所以这甚至不是“错误的”,因为尽管经过了技术上的签名,但实际值始终是未签名的(因为从未设置过符号位)。
它还有助于避免将退出代码与进行比较的常见错误,即使程序退出时-1
,由于某种奇怪的原因,该错误也似乎不会出现-1
(嗯,猜猜为什么!)。
关于最后一点,从函数返回,如果此函数恰好是main
,则请参见上文。否则,它取决于函数的返回类型,原则上可以是任何值(包括void
)。
waitid()
推出之前,您一直是对的。
waitid()
只是做相同的事情,略有不同。它等待一个特定的id或任何线程,然后将结果写入指向的siginfo_t
结构所在的si_status
位置int
(如此... signed,一样)。尽管如此,exit()
只传递最低的8位,所以...完全相同。
exit()
将参数的所有32位传递给内核,并waitid()
从退出代码返回所有32位。也许您在Linux上检查了没有人愿意修复错误的地方。如果您不相信我,请在
exit
,特别是“说明”下的第二行,其中指出:“尽管只有最低有效的8位(即状态&0377)对等待的父进程可用。 “。符合标准的实现就是这样工作的-最低的8位而不是32位。您有传递32位的参考吗?
waitid()
并且siginfo_t
传递给SIGCHLD
处理程序的结构返回exit()
参数的所有32位。
- 从二进制可执行文件(例如:C程序)返回的退出代码。
- 从bash脚本返回的退出代码(调用exit时)。
任何进程的退出码(无论是二进制可执行文件,shell脚本还是其他任何东西)的范围都在0到255之间。可以将一个较大的值传递给exit()
,但是只有状态的低8位可用于通过其他过程wait()
。
- 从函数返回的退出代码(调用return时)。我认为这是介于0和255之间。
可以将AC函数声明为几乎返回任何类型。其返回值的限制是由类型完全取决于:例如,-128到127,用于一个函数返回signed char
,或0至4.2十亿为一个函数返回unsigned int
,或者任何浮点数至多并包括inf
用于返回的功能double
。这还不包括非数字类型,例如void *
或struct
...
return
当然是外壳程序内置程序。