ExitCodes大于255,可能吗?

问题描述 投票:32回答:3

如果是,是在哪个操作系统,shell或其他操作系统上?

考虑以下java程序(我仅以java为例,使用任何语言都可以解决此问题,更多有关操作系统):

public class ExitCode {
    public static void main(String args[]) {
        System.exit(Integer.parseInt(args[0]));
    }
}

在Linux和bash上运行它,它总是返回小于255的值,例如(echo $?打印先前执行的命令的退出代码)

> java ExitCode 2; echo $?
2

> java ExitCode 128; echo $?
128

> java ExitCode 255; echo $?
255

> java ExitCode 256; echo $?
0

> java ExitCode 65536; echo $?
0

编辑:(到目前为止,到目前为止)唯一的答案充分说明了在UNIX上发生的情况。我仍然想知道其他操作系统。

shell operating-system exit-code
3个回答
33
投票

使用wait()waitpid()

在Unix和使用POSIX函数(例如wait()wait()的派生类中,这是不可能的。返回的退出状态信息由两个8位字段组成,一个字段包含退出状态,另一个字段包含有关死亡原因的信息(0表示在程序控制下有序退出,其他值指示信号杀死了它,并指示是否杀死了该信号。核心已被丢弃)。

waitpid()waitpid()一起使用

[如果您努力工作,并且阅读sigaction()SA_SIGINFOsigaction()的POSIX规范,您会发现您可以保留子进程传递给sigaction()的32位值。但是,这并不完全简单。

<signal.h>

运行(从<signal.h>编译程序Signal Actions时,将产生如下输出:]

exit()

删除了对#include <errno.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <time.h> #include <unistd.h> static siginfo_t sig_info = { 0 }; static volatile sig_atomic_t sig_num = 0; static void *sig_ctxt = 0; static void catcher(int signum, siginfo_t *info, void *vp) { sig_num = signum; sig_info = *info; sig_ctxt = vp; } static void set_handler(int signum) { struct sigaction sa; sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = catcher; sigemptyset(&sa.sa_mask); if (sigaction(signum, &sa, 0) != 0) { int errnum = errno; fprintf(stderr, "Failed to set signal handler (%d: %s)\n", errnum, strerror(errnum)); exit(1); } } static void prt_interrupt(FILE *fp) { if (sig_num != 0) { fprintf(fp, "Signal %d from PID %d (status 0x%.8X; UID %d)\n", sig_info.si_signo, (int)sig_info.si_pid, sig_info.si_status, (int)sig_info.si_uid); sig_num = 0; } } static void five_kids(void) { const int base = 0xCC00FF40; for (int i = 0; i < 5; i++) { pid_t pid = fork(); if (pid < 0) break; else if (pid == 0) { printf("PID %d - exiting with status %d (0x%.8X)\n", (int)getpid(), base + i, base + i); exit(base + i); } else { int status = 0; pid_t corpse = wait(&status); if (corpse != -1) printf("Child: %d; Corpse: %d; Status = 0x%.4X - waited\n", pid, corpse, (status & 0xFFFF)); struct timespec nap = { .tv_sec = 0, .tv_nsec = 1000000 }; // 1 millisecond nanosleep(&nap, 0); prt_interrupt(stdout); fflush(0); } } } int main(void) { set_handler(SIGCHLD); five_kids(); } 的一毫秒调用,输出看起来像:

sigexit73

请注意,这里只有三行以sigexit73.c开头,也只有三行以$ sigexit73 PID 26599 - exiting with status -872349888 (0xCC00FF40) Signal 20 from PID 26599 (status 0xCC00FF40; UID 501) Child: 26600; Corpse: 26599; Status = 0x4000 - waited PID 26600 - exiting with status -872349887 (0xCC00FF41) Signal 20 from PID 26600 (status 0xCC00FF41; UID 501) Child: 26601; Corpse: 26600; Status = 0x4100 - waited PID 26601 - exiting with status -872349886 (0xCC00FF42) Signal 20 from PID 26601 (status 0xCC00FF42; UID 501) Child: 26602; Corpse: 26601; Status = 0x4200 - waited PID 26602 - exiting with status -872349885 (0xCC00FF43) Signal 20 from PID 26602 (status 0xCC00FF43; UID 501) Child: 26603; Corpse: 26602; Status = 0x4300 - waited PID 26603 - exiting with status -872349884 (0xCC00FF44) Signal 20 from PID 26603 (status 0xCC00FF44; UID 501) $ 结尾;一些信号和退出状态会丢失。这可能是由于nanosleep()信号被设置为父进程之间的时序问题。

但是,关键是当代码使用$ sigexit73 sigexit23 PID 26621 - exiting with status -872349888 (0xCC00FF40) Signal 20 from PID 26621 (status 0xCC00FF40; UID 501) Child: 26622; Corpse: 26621; Status = 0x4000 - waited PID 26622 - exiting with status -872349887 (0xCC00FF41) PID 26623 - exiting with status -872349886 (0xCC00FF42) Signal 20 from PID 26622 (status 0xCC00FF41; UID 501) Child: 26624; Corpse: 26623; Status = 0x4200 - waited Signal 20 from PID 26623 (status 0xCC00FF42; UID 501) Child: 26625; Corpse: 26622; Status = 0x4100 - waited PID 26624 - exiting with status -872349885 (0xCC00FF43) PID 26625 - exiting with status -872349884 (0xCC00FF44) $ Signalwaited跟踪状态时,可以在SIGCHLD状态下传输4个字节的数据。

仅作记录,该测试是使用GCC 9.2.0和XCode 11.3.1在运行macOS Mojave 10.14.6的MacBook Pro上进行的。该代码也可以在我在GitHub上的exit()(堆栈溢出问题)存储库中以sigaction()子目录中的文件SIGCHLD的形式使用。


13
投票

在现代Windows上,操作系统本身以及默认的控制台外壳(SA_SIGINFO)至少在整个32位带符号整数的整个范围内接受并显示退出代码。在SOQ中运行上面的示例将提供您要求的退出代码:

sigexit73.c

Windows并没有真正意义上的Unix信号的概念,它也不试图劫持出口代码以添加额外的信息,只要您的shell(或任何程序最终读取出口代码)都不会这样做或者,您应该找回返回的退出代码。幸运的是,使用Microsoft C运行时的程序(包括使用MS Visual C ++编译的所有程序)将保留退出程序的退出代码。


1
投票

Windows的退出代码更多,超过14,000。 (我确信您经常在自己的屏幕上看到其中的一些)。

这里:

© www.soinside.com 2019 - 2024. All rights reserved.