非零退出状态,用于干净退出


15

如果相关程序正常运行,返回非零退出代码是否可以接受?例如,假设我有一个简单的程序(仅)执行以下操作:

程序接受N个参数。它返回退出代码min(N,255)。请注意,任何N对该程序均有效。

一个更现实的程序可能会返回不同的代码,以成功运行表示不同事物的程序。这些程序是否应该将该信息写到流中,例如stdout?

Answers:


24

这取决于环境,但是我会说它的风格很差。

类似Unix的系统有一个严格的约定,退出状态0表示成功,而任何非零退出状态表示失败。一些(但不是全部)程序可以区分具有不同的非零退出代码的不同类型的故障。例如grep,如果找到了模式,通常返回0,否则返回1,如果出现错误(例如文件丢失),则返回2(或更多)。

这个约定很难连接到Unix shell中。例如,在shbash和其他类似Bourne的shell中,该if语句将0退出状态视为成功/真,将非零退出状态视为失败/假:

if your-command
then
    echo ok
else
    echo FAILURE
fi

我相信MS Windows下的约定是相似的。

现在肯定没有什么可以阻止您编写使用非常规退出代码的程序,尤其是如果没有其他东西要与之交互的话,但是请注意您违反了一个已建立好的约定,以后它可能会回来咬住您。

程序返回此类信息的通常方法是将其打印到stdout

status = $(your-command)
echo Result is $status

7
+1解释约定,如果我把它set -e放在某个地方,这种方法会破坏我的大多数shell脚本。
本杰明·班尼尔

与相似grepdiff找到差异时返回1;否则返回1。如果发生错误,则> 1。
7heo.tk 2015年

6

取决于您的环境期望。

我最喜欢的维基百科

在OpenVMS中,成功由奇数表示,失败由偶数表示。该值是一个32位整数,带有以下子字段:控制位,设备号,消息号和严重性。严重性值分为成功(成功,信息)和失败(警告,错误,致命)。


4

我认为,如果退出代码向调用者返回有意义的相关信息,并且成功的定义不是真正的二进制,则有先例。我想到的先例是robocopy,它根据发生的事情返回许多不同的东西

我要补充一点,由于这个原因,我们总是总是要进行调试-大多数实用程序都假定退出代码0 ==成功,所以当robocopy返回1时会感到惊讶,因为它复制的内容不是零,因为它没有复制内容,但是没有也不会出现错误。


2

不为成功运行而返回0是一个坏主意,因为它可能会使运行程序的人感到困惑。如果有些人使用不同的输入将您的程序运行了100多次,并且想知道有多少失败或成功完成,那么拥有一个成功值将比拥有许多不同的值更容易发现差异。

如果您的程序具有多个成功的返回路径,这些路径都可以表示不同的事物,那么我想说这是您的程序设计不良的标志。


2

我知道我认为可以接受的情况。我知道一个测试框架会随着测试失败的总数而退出。因此,例如,如果测试运行器完成但没有失败的测试,则退出时为零。如果一项测试失败,即使测试运行器本身正确运行,它也将以1退出。如果两项失败,则返回2,依此类推。直到250,这表示“ 250或更多测试失败”。

它使用退出代码> 250表示异常退出。

虽然这违反约定,但在实践中效果很好。


3
我不认为这确实违反了约定-如果没有错误,则测试成功。任何非零结果代码表示测试失败。
Bevan 2012年

1
那就是“退出时会显示错误状态,以指示多个错误,并且可能会违反退出状态的确切通用语义,但它肯定不会违反较大的“ 0是可以的,大于0的任何内容都是错误”的约定。
Vatine 2012年

2

这实际上取决于您尝试使用代码传达的内容。例如,如果找不到数据,则DB2返回100;对于警告,其他各种正值;对于错误,则返回负值。Oracle做类似的事情。

因此,如果存在不同的成功状态,则可能值得使用变化的返回值。


2

一个很好的例子:男人SA-更新(SpamAssassin的)

退出代码

  • 如果未指定--checkonly,则退出代码为0表示有可用的更新,并且已成功下载并安装。
  • 退出代码为1表示没有新的更新可用。
  • 退出代码2表示...

在这种情况下,出口1仅是信息性代码。但是,如果我会编写代码,则不会选择1,因为那通常是电源故障。

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.