Python中的退出代码


207

我收到一条消息说script xyz.py returned exit code 0。这是什么意思?

Python中的退出代码是什么意思?那里有多少?哪些重要?


1
您在哪里看到此消息?
杰里米·坎特雷尔

1
@Jeremy在PythonWin的底部。
深潭

Answers:


223

您在脚本中寻找的是对的调用sys.exit()。该方法的参数作为退出代码返回到环境。

该脚本很可能从未调用过exit方法,并且0是默认的退出代码。


12
完全不确定。在Unix / Linux中,标准是:在一切正常的情况下退出0。键入命令,然后回显$ ?:如果您读取0,则返回时无错误。想法是进行标准测试。如果代码xyz.py没有遇到任何错误,则应该返回0!
布鲁诺·冯·巴黎

1
如果您想更改退出代码,更喜欢使用内置的退出程序干净退出,请参见此答案
vidstige

101

文档中sys.exit

可选参数arg可以是给出退出状态的整数(默认为零),也可以是其他类型的对象。如果它是整数,则shell等将零视为“成功终止”,而将任何非零值视为“异常终止”。大多数系统要求它的范围是0-127,否则会产生不确定的结果。某些系统具有为特定的退出代码分配特定含义的约定,但是这些通常不完善。Unix程序通常将2用于命令行语法错误,将1用于所有其他类型的错误。

在外壳程序脚本中使用退出代码的一个示例。在bash中,您可以检查特殊变量$?的最后退出状态:

me@mini:~$ python -c ""; echo $?
0
me@mini:~$ python -c "import sys; sys.exit(0)"; echo $?
0
me@mini:~$ python -c "import sys; sys.exit(43)"; echo $?
43

我个人尝试使用在/usr/include/asm-generic/errno.hLinux系统上找到的退出代码,但是我不知道这样做是否正确。


3
在另一篇文章中,我找到了此链接:tldp.org/LDP/abs/html/exitcodes.html 可能有用。:)
艾格峰(Eigir)

9
errno.h通常用于函数调用退出代码。尝试标准化程序退出代码已导致/usr/include/sysexits.h存在于大多数POSIX系统上。
mpounsett

1
非常高兴知道“ Unix程序通常将2用于命令行语法错误”!
丹迪斯顿

2
@dantiston 同意。死忠于羊毛的Gentoo拥护者,但直到今天,我才知道……。(我的耻辱现在结束了。)相关地,请注意,当没有行匹配并且出现实际错误时,grep通过退出退出打破这种趋势。非常感谢,斯托曼。12
Cecil Curry

32

作为记录,您可以使用此处定义的POSIX标准退出代码。

例:

import sys, os

try:
    config()
except:
    sys.exit(os.EX_CONFIG) 
try:
    do_stuff()
except:
    sys.exit(os.EX_SOFTWARE)
sys.exit(os.EX_OK) # code 0, all ok

3
根据文档,这些仅在Unix操作系统上可用,因此不能完全移植。
凤凰城

1
如果您希望所有操作系统上都提供可移植的POSIX代码,请参阅exitstatusPyPI软件包。
凤凰城'18

1
该软件包的整体是0(表示成功)和1(表示失败)。
帕维尔·米纳夫

25

有一个errno模块定义标准退出代码:

例如,权限被拒绝是错误代码13

import errno, sys

if can_access_resource():
    do_something()
else:
    sys.exit(errno.EACCES)

36
这是不正确的。这些errno不能用作流程退出代码。这些是旨在在程序内部使用的低级错误代码,尤其是那些用C语言编写的错误代码。对于Python,请尽可能使用异常。
SvdB

2
你是对的。这些将在内部使用。但是您通常不会在最终用户级别引发异常。您使用sys.exit(x),其中x是您任意选择的整数。但是您可以使用以EX_开头并在'os'模块中定义的代码。像os.EX_OK或os.EX_IOERR
Oli

2
抱歉,但我也对此表示反对,因为它具有误导性。出口状态码和错误号不可互换/互补。在给定的示例中,“权限被拒绝”的错误代码为13(根据errnoerrno.h),而退出状态代码为77(根据ossysexits.h)。发出前者的程序是非标准的(事实上是法律上的),并且与希望正确使用后者的其他程序不能很好地配合使用。
Mark G.

14

退出代码0通常表示“这里没有问题”。但是,如果脚本的程序员未遵循约定,则可能必须查阅源代码以了解其含义。通常,将非零值作为错误代码返回。


6

答案是“取决于零退出码的含义”

但是,在大多数情况下,这意味着“一切都很好”


我喜欢POSIX:

因此,在外壳上,我将输入:

python script.py && echo 'OK' || echo 'Not OK'

如果我的python脚本调用,sys.exit(0)则外壳返回“ OK”

如果我的python脚本调用sys.exit(1)(或任何非零整数),则外壳程序返回“不正确”

了解外壳程序是您的工作,并阅读脚本的文档(或源代码)以了解退出代码的含义。


仅出于完整性考虑,如果Python脚本引发错误或语法错误,则会打印“ Not OK”。
Shital Shah

5

操作系统命令具有退出代码。查找linux退出代码,以了解有关此内容的一些信息。外壳程序使用退出代码来确定程序是否正常运行,出现问题或失败。已经做了一些努力来创建标准(或至少是常用的)退出代码。请参阅此高级Shell脚本发布。


5

我建议使用内置的exit(0)进行干净关机,而不要使用sys.exit()

我不确定这是否是个好建议。

提到的文档非常如此

站点模块(在启动期间会自动导入,除非指定了-S命令行选项)会向内置名称空间添加多个常量。它们对于交互式解释器外壳很有用,不应在程序中使用

然后:

退出(代码=无)

对象,在打印时会打印一条消息,例如“使用quit()或Ctrl-D(即EOF)退出”,并在调用时使用指定的退出代码引发SystemExit。

如果将它与sys.exit()文档进行比较,则它使用的是引发SystemExit异常的相同机制。


5

如果你想移植应用的标准POSIX退出代码,请参阅exitstatusPyPI上的包。

安装软件包:

$ pip install exitstatus

在您的代码中使用:

import sys
from exitstatus import ExitStatus

sys.exit(ExitStatus.success)

4

退出代码仅具有脚本作者指定的含义。Unix的传统是退出代码0表示“成功”,其他都是失败的。确保给定脚本的退出代码意味着什么的唯一方法是检查脚本本身。


2

许多编程语言中的退出代码取决于程序员。因此,您必须查看程序源代码(或手册)。零通常表示“一切正常”。


-2

为了允许执行异常处理程序和其他操作,我建议使用 exit(0)内置而不要使用sys.exit()它来突然终止进程。


那有什么区别呢?这些信息从何而来?您是指执行“出口”处理程序,还是指的是什么?SystemExit似乎以任何一种方式提高。
0xC0000022L

嗯,我很困惑os._exit,两者似乎都提高了SystemExit
vidstige

1
错误:sys.exit() 关机干净,就像exit()。他们俩都做同样的事情:提出一个SystemExit例外。实际上,exit()它是用于交互式会话的,而不是脚本的,因此从概念上讲sys.exit() 所指示的。您可能会与混淆os._exit(),那是突然终止的那一个。
MestreLion
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.