如何获得退出代码(和/或返回代码)列表以及命令/实用程序的含义?


17

有什么办法可以执行终端命令标题中所述的内容,还是必须查看代码?

Answers:


15

没有“配方”来获取给定终端命令的退出状态的含义。

我的第一个尝试是联机帮助页:

user@host:~# man ls 
   Exit status:
       0      if OK,

       1      if minor problems (e.g., cannot access subdirectory),

       2      if serious trouble (e.g., cannot access command-line argument).

第二谷歌。请参阅wget作为示例。

第三:shell的退出状态,例如bash。Bash及其内置函数可能会特别使用125以上的值。127表示找不到命令,126表示命令不可执行。有关更多信息,请参见bash退出代码


是的,有些人,信息,...页面中确实包含这些信息。而我担心那些没有的人。..我知道网络研究始终是一种选择。..目前看来,这只是我必须寻找的bash退出代码。–
精确

12

退出代码表示结束程序时的失败状态,并且介于0到255之间。shell及其内置函数可能会特别使用125以上的值来表示特定的失败模式,因此代码列表在shell和操作系统之间可能会有所不同(例如Bash)使用值128 + N作为退出状态)。请参阅:Bash-3.7.5退出状态man bash

通常,退出状态为零表示命令成功,退出状态为非零表示失败

要检查哪些错误代码是由命令返回,你可以打印$?最后退出代码或${PIPESTATUS[@]}这给从退出状态值的列表管道(中的Bash)shell脚本退出后。

找不到所有退出代码的完整列表,但是已经尝试在内核源代码中对退出状态编号进行系统化,但这主要是针对C / C ++程序员的,并且类似的脚本标准可能是合适的。

可以在/usr/include/sysexits.h(或:man sysexits在BSD上)找到Linux和BSD / OS X上的一些sysexits列表,以及程序的首选退出代码(64-78 ):

0   /* successful termination */
64  /* base value for error messages */
64  /* command line usage error */
65  /* data format error */
66  /* cannot open input */
67  /* addressee unknown */
68  /* host name unknown */
69  /* service unavailable */
70  /* internal software error */
71  /* system error (e.g., can't fork) */
72  /* critical OS file missing */
73  /* can't create (user) output file */
74  /* input/output error */
75  /* temp failure; user is invited to retry */
76  /* remote error in protocol */
77  /* permission denied */
78  /* configuration error */
/* maximum listed value */

上面的列表分配了以前未使用的64-78退出代码。将来未分配的退出代码范围将进一步受到限制。

但是,以上值主要用于sendmail中,几乎没有其他人使用,因此它们与标准(如@Gilles所指出的)远非遥不可及

在shell中,退出状态如下(基于Bash):

  • 1-- 125命令未成功完成。检查命令的手册页以了解状态的含义,以下是一些示例:

  • 1 -常见错误

    其他错误,例如“被零除”和其他不允许的操作。

    例:

    $ let "var1 = 1/0"; echo $?
    -bash: let: var1 = 1/0: division by 0 (error token is "0")
    1
    
  • 2 -滥用shell内置函数(根据Bash文档)

    缺少关键字或命令,或权限问题(二进制比较文件失败时,diff返回代码)。

    例:

     empty_function() {}
    
  • 6 -没有这样的设备或地址

    例:

    $ curl foo; echo $?
    curl: (6) Could not resolve host: foo
    6
    
  • 124 -命令超时

  • 125-如果命令本身失败,请参阅:coreutils
  • 126 -如果找到命令但无法调用(例如,不可执行)

    权限问题或命令不是可执行文件。

    例:

    $ /dev/null
    $ /etc/hosts; echo $?
    -bash: /etc/hosts: Permission denied
    126
    
  • 127 -如果找不到命令,则创建执行该命令的子进程将返回该状态

    可能有问题$PATH或错字。

    例:

    $ foo; echo $?
    -bash: foo: command not found
    127
    
  • 128 -的参数无效 exit

    exit仅接受0-255范围内的整数args。

    例:

    $ exit 3.14159
    -bash: exit: 3.14159: numeric argument required
    
  • 128-- 254致命错误信号“ n”-命令由于接收到信号而死亡。信号代码被添加到128(128 + SIGNAL)中以获得状态(Linux:man 7 signal,BSD:)man signal,下面是几个示例:

  • 130 -由于按下Ctrl-C而终止命令,130-128 = 2(SIGINT)

    例:

    $ cat
    ^C
    $ echo $?
    130
    
  • 137-如果命令已发送KILL(9)信号(128 + 9),否则退出命令状态

    kill -9 $PPID 脚本。

  • 141 -- SIGPIPE -对没有读者的管道写

    例:

    $ hexdump -n100000 /dev/urandom | tee &>/dev/null >(cat > file1.txt) >(cat > file2.txt) >(cat > file3.txt) >(cat > file4.txt) >(cat > file5.txt)
    $ find . -name '*.txt' -print0 | xargs -r0 cat | tee &>/dev/null >(head /dev/stdin > head.out) >(tail /dev/stdin > tail.out)
    xargs: cat: terminated by signal 13
    $ echo ${PIPESTATUS[@]}
    0 125 141
    
  • 143 -命令以信号代码15终止(128 + 15 = 143)

    例:

    $ sleep 5 && killall sleep &
    [1] 19891
    $ sleep 100; echo $?
    Terminated: 15
    143
    
  • 255*-退出状态超出范围。

    exit仅接受0-255范围内的整数args。

    例:

    $ sh -c 'exit 3.14159'; echo $?
    sh: line 0: exit: 3.14159: numeric argument required
    255
    

根据上表,退出代码1-2、126-165和255具有特殊含义,因此对于用户指定的退出参数应避免使用。

请注意,超出范围的退出值可能会导致意外的退出代码(例如,退出3809给出的退出代码为225,3809%256 = 225)。

看到:


errno值由系统API使用,它们不用作退出状态(它们甚至不在正确的范围内),并且与Shell脚本无关。Sysexits值来自sendmail,几乎没有人使用过,它们与标准几乎没有什么不同。
吉尔(Gilles)“所以,别再邪恶了”

7

您将必须查看代码/文档。但是,最接近“标准化”的是errno.h


感谢您指向头文件..尝试调查了一些实用程序的文档..很难找到退出代码,似乎大多数将是标准错误...
精确

3
errno.h与退出代码无关,仅与错误消息有关。
吉尔斯(Gilles)'所以

如所示,大多数程序会根据BSD约定返回退出代码sysexits.h。但是,某些程序确实会返回errnos,而我实际上认为返回errnos最有意义。未处理的errnos会像异常一样向上传播(停顿errno,函数返回例如-10|NULL)。由于程序只是函数,尽管函数在单独的地址空间中运行,所以有意义的是程序可能希望继续errno跨进程边界进行传播。
PSkocik

@PSkocik,您有这样的命令示例吗?errnos不是可移植的(值在系统之间不一致),并且没有可移植的方法来从值中获取err名称或消息(zsh具有内置功能)。更不用说某些系统的errno大于123,这将与常见的特殊含义错误代码发生冲突。通常,命令从errno打印消息,并返回成功/失败退出状态。命令适用于用户。函数/系统调用供程序员使用。
斯特凡Chazelas

@StéphaneChazelas我已经看过几次了,但是我得承认,在任何完善的程序中都没有。我最近一直在自己的玩具系统中返回errno + 1(因此1继续表示“任何错误”),因为我认为跨过程边界序列化errno的意义要比根据BSD约定进行翻译的意义更大,因为程序执行是本质上是函数调用,而函数使用errno。我在PROMPT_COMMAND(bash)中使用了自己的最后退出状态解码器,所以得到了类似的信息"($numeric_code|$bsd_decoded|$errno_plus_one_decoded)"
PSkocik '16

1

据我所知,只有两个或多或少的标准值-都定义stdlib.h为与exit()一起使用:

  • EXIT_SUCCESS(= 0)
  • EXIT_FAILURE(= 1)

而且,事实上的标准值,即对于世界上所有程序都具有相同的含义,是0(零),代表SUCCESS。

不同的程序会引入不同的返回“失败”代码列表,以区分或强调不同的错误(不同的类型或严重性)。一些程序甚至使用返回的值报告发现的运行时错误的整数数量(例如,诉讼中失败的单元测试的数量)。

我不建议引入任何类型的“新标准”来扩展 stdlib.h

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.