Linux 中退出代码的最小值和最大值是多少?

Linux 中退出代码的最小值和最大值是多少?

Linux 中以下退出代码的最小值和最大值是多少:

  1. 从二进制可执行文件(例如:C 程序)返回的退出代码。
  2. 从 bash 脚本返回的退出代码(调用时exit)。
  3. 从函数返回的退出代码(调用时return)。我认为这是在0和之间255

答案1

_exit()传递给/系统调用的号码exit_group()(有时称为退出代码以避免歧义退出状态它也指退出代码或信号号以及附加信息的编码,具体取决于进程是否被终止或正常退出)的类型int,因此在像 Linux 这样的类 Unix 系统上,通常是一个 32 位整数,其值来自 - 2147483648 (-2 31 ) 至 2147483647 (2 31 -1)。

但是,在所有系统上,当父进程(或子子收割机或init父进程死亡)使用wait(), waitpid(), wait3(),wait4()系统调用来检索它时,只有它的低 8 位可用(值 0 到 255 (2 8 - 1))。

当使用waitid()API(或 SIGCHLD 上的信号处理程序)时,在大多数系统上(以及POSIX 现在在 2016 版标准中更加明确地要求(看_exit()规格)),完整的数字是可用的(在si_status返回结构的字段中)。 Linux 上的情况并非如此,尽管 Linux 也使用waitid()API 将数字截断为 8 位,不过这种情况将来可能会改变。

一般来说,您只想使用 0(通常表示成功)到 125 之间的值,因为许多 shell 在其$?表示中使用高于 128 的值退出状态对被终止进程的信号编号进行编码,特殊情况下编码为 126 和 127。

您可能希望使用 126 到 255 来exit()表示与 shell 的含义相同的内容$?(就像脚本的含义一样ret=$?; ...; exit "$ret")。使用 0 -> 255 之外的值通常没有用。通常,只有当您知道父级将waitid()在不截断的系统上使用 API 并且您恰好需要 32 位范围的值时,您才会这样做。请注意,如果您做了一个exit(2048)例子,使用传统 API 的家长将认为这是成功的wait*()

更多信息请访问:

该问答应该有望回答您的大部分其他问题并阐明退出状态。我将添加更多内容:

进程不能终止,除非它被杀死或调用_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 会保留未定义的行为。

如果您这样做,某些 shell 会显示一些意外行为:

  • bashmksh但不是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 以某种方式鼓励这种行为,但它正在被恢复

答案2

最小值为0,这被认为是成功值。其他的都是失败。最大值255也称为-1

这些规则适用于脚本和其他可执行文件以及 shell 函数。

较大的值会以 256 为模。

答案3

这看起来很简单,但是哦,天哪。

C 语言(以及随后直接或间接的大多数其他语言)要求 from 的返回main等效于使用exit与返回值相同的参数进行调用。这是一个整数(返回类型非常明确int),因此原则上范围是INT_MININT_MAX

然而,POSIX 状态只有传递给的最低 8 位exit可供等待的父进程使用,字面上就好像它是“状态&0xFF”
因此,实际上,退出代码是一个(仍然有符号的)整数,其中仅设置了最低 8 位。

因此最小值将为 -128 ,最大值为 127。等等,这不是真的。它将是 0 到 255。

可惜,当然不可能那么简单。实际上,Linux(或者更确切地说 bash)做得不同。返回码的有效范围是0 到255(即无符号)。

为了避免混淆,为了安全起见,最好只认为返回码是无符号的,并将返回的任何内容转换为wait无符号。这样它就与您在 shell 中看到的一致。由于最高位(包括最高位)被清除,这甚至不是“错误”,因为尽管技术上有符号,但实际值始终是无符号的(因为符号位从未设置)。
它还有助于避免将退出代码与 进行比较的常见错误-1,这由于某种奇怪的原因即使程序退出时似乎也不会出现-1(好吧,猜猜为什么!)。

关于你的最后一点,从函数返回,如果这个函数恰好是main,那么请参见上面。否则,这取决于函数的返回类型是什么,原则上可以是任何事物(包括void)。

答案4

  1. 从二进制可执行文件(例如:C 程序)返回的退出代码。
  2. 从 bash 脚本返回的退出代码(调用 exit 时)。

任何进程的退出代码(无论是二进制可执行文件、shell 脚本还是其他任何进程)的范围从 0 到 255。可以将更大的值传递给exit(),但只能使用状态的低 8 位其他流程通过wait().

  1. 从函数返回的退出代码(调用 return 时)。我认为这个值在 0 到 255 之间。

AC 函数可以声明为返回几乎任何类型。其返回值的限制完全由该类型决定:例如,对于返回 的函数signed char,为 -128 到 127;对于返回 的函数,为 0 到 42 亿;对于返回 的函数unsigned int,返回值的范围为0 到 42 亿。这还不包括非数字类型,例如或 a ...infdoublevoid *struct

相关内容