【问题标题】:Exit codes in PythonPython中的退出代码
【发布时间】:2010-09-22 01:36:22
【问题描述】:

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

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

【问题讨论】:

  • 你在哪里看到这条消息?
  • @Jeremy 在 PythonWin 的底部。

标签: python exit-code


【解决方案1】:

跟随Unix exit codes 0 - 成功/OK,1 - 不成功/错误。您可以简单地使用exit(0)exit(1) 调用而不导入sys 模块。

【讨论】:

【解决方案2】:

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

但是,在大多数情况下,这意味着“一切正常”。


我喜欢 POSIX:

所以,在 shell 中,我会输入:

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

如果我的 Python 脚本调用 sys.exit(0),shell 返回“OK”

如果我的 Python 脚本调用 sys.exit(1)(或任何非零整数),shell 将返回“Not OK”。

您的工作是精通 shell,并阅读脚本的文档(或源代码)以了解退出代码的含义。

【讨论】:

  • 为了完整起见,如果 Python 脚本出现错误或语法错误,将打印“Not OK”。
【解决方案3】:

操作系统命令有退出代码。查找Linux exit codes 以查看有关此的一些材料。 shell 使用退出代码来决定程序是否工作、有问题或失败。有一些努力来创建标准(或至少是常用的)退出代码。请参阅此Advanced Shell Script 帖子。

【讨论】:

    【解决方案4】:

    来自sys.exit 的文档:

    可选参数 arg 可以是 给出退出状态的整数 (默认为零),或其他类型 的对象。如果是整数,则为零 被视为“成功终止” 并且考虑任何非零值 炮弹的“异常终止”和 类似。大多数系统都要求它 在 0-127 范围内,并产生 否则未定义的结果。一些 系统有一个约定 赋予特定含义 特定的退出代码,但这些是 普遍欠发达; Unix 程序通常使用 2 作为命令 行语法错误,所有其他错误为 1 各种错误。

    使用退出代码的一个示例是在 shell 脚本中。在 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.h 中找到的退出代码(在 Linux 系统上),但我不知道这样做是否正确。

    【讨论】:

    • 从另一篇文章中我找到了这个链接:tldp.org/LDP/abs/html/exitcodes.html 可能有用。 :)
    • errno.h 通常用于函数调用退出代码。标准化程序退出代码的尝试导致 /usr/include/sysexits.h 出现在大多数 POSIX 系统上。
    • 很高兴知道“Unix程序一般使用2表示命令行语法错误”!
    • @dantiston 同意。 顽固的 Gentoo 拥护者,但我从来不知道......直到这命运的一天。 (我的耻辱现在结束了。)相关地,请注意grep 打破了这一趋势,当没有行匹配时以1 退出,而在实际错误时以2 退出。非常感谢,斯托曼。
    【解决方案5】:

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

    脚本很可能从未调用 exit 方法,而 0 是默认退出代码。

    【讨论】:

    • 完全不确定。在 Unix/Linux 中,标准是:在一切正常的情况下退出 0。键入命令,然后回显 $?: 如果您读取 0,则返回没有错误。我们的想法是进行标准测试。如果代码 xyz.py 没有遇到任何错误,它应该返回 0!
    • 如果您想更改退出代码,更喜欢使用内置的 exit 干净地退出,请参阅this answer
    • @vidstige:exit()“内置”(它实际上并不是一直都是内置的;例如,当 Python 使用 -S 开关运行时它不会存在)是错误的解决方案;你想要sys.exit()(它实际上干净/一致地退出),而不是exit()(允许被工具替换为奇怪的东西,sys.exit 通常应该保持不变)。 “不干净的退出”函数是os._exit(),它会突然终止(它主要用于在基于forkmultiprocessing 场景中杀死工作人员,以避免调用父进程在fork 之前设置的清理)。
    【解决方案6】:

    如果您想以便携方式使用 standard POSIX exit codes,请参阅 PyPI 上的 exitstatus 包。

    安装包:

    $ pip install exitstatus
    

    在您的代码中使用:

    import sys
    from exitstatus import ExitStatus
    
    sys.exit(ExitStatus.success)
    

    【讨论】:

      【解决方案7】:

      我建议使用内置的 exit(0) 彻底关闭,而不是使用 sys.exit()

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

      The very documentation mentioned 读作:

      站点模块(在启动期间自动导入,除非给出了 -S 命令行选项)将几个常量添加到内置命名空间。它们对于交互式解释器 shell 很有用,不应在程序中使用

      然后:

      退出(代码=无)

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

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

      【讨论】:

        【解决方案8】:

        为了允许异常处理程序和其他事情执行,我建议使用内置的exit(0) 彻底关闭而不是使用突然终止进程的sys.exit()

        【讨论】:

        • 那有什么区别呢?这些信息来自哪里?您是指执行“退出”处理程序还是您指的是什么?无论哪种方式,SystemExit 似乎都被提升了。
        • mm,我把它和os._exit 混淆了,两者似乎都提高了SystemExit
        • 错误:sys.exit() 确实完全关闭,就像exit()一样。他们都做相同的事情:引发SystemExit异常。实际上,exit() 用于交互式会话,而不是脚本,所以从概念上讲,sys.exit() 指定的会话。你可能对os._exit() 感到困惑,那是突然终止的那个。
        • 添加到@MestreLion: exit() 甚至不是真正的内置; it's jammed into the built-ins after the fact when the site module is imported。这在大多数情况下都会隐式发生,但是对于试图快速运行并且不依赖第三方模块(安装在 site-packages 中)的 Python 脚本,可以使用 -S 开关来禁用导入site 完全不存在,exit() 将不存在(sys.exit() 仍然存在)。
        【解决方案9】:

        作为记录,您可以使用定义为 here 的 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
        

        【讨论】:

        • 根据docs,这些仅在 Unix 操作系统上可用,因此不能完全移植。
        • 如果您想要可在所有操作系统上使用的可移植 POSIX 代码,请参阅 exitstatus PyPI 包。
        • 该包的整体为 0 表示成功,1 表示失败。
        • 我以为你在开玩笑,帕维尔。其实你不是在开玩笑:github.com/johnthagen/exitstatus/blob/master/exitstatus.py
        【解决方案10】:

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

        例如,Permission denied是错误代码13

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

        【讨论】:

        • 这是不正确的。这些 errno 不打算用作进程退出代码。这些是旨在在程序内部使用的低级错误代码,特别是用 C 语言编写的那些。对于 Python,尽可能使用异常。
        • 你是对的。这些将在内部使用。但是您通常不会在最终用户级别引发异常。您使用 sys.exit(x) ,其中 x 是您任意选择的整数。但是您可以使用以 EX_ 开头并在“os”模块中定义的那些。像 os.EX_OK 或 os.EX_IOERR
        • 对不起,但我也反对这一点,因为它具有误导性。退出状态代码和错误号不可互换/互补。使用给定的示例,“permission denied”的 error code 为 13(根据 errnoerrno.h),但 exit status code 为 77(根据到ossysexits.h)。发出前者的程序是非标准的(de facto vel jure),并且不会与正确期望后者的其他程序很好地配合。
        【解决方案11】:

        许多编程语言的退出代码由程序员决定。所以你必须查看你的程序源代码(或手册)。零通常意味着“一切顺利”。

        【讨论】:

          【解决方案12】:

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

          【讨论】:

            【解决方案13】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-06-27
              • 2019-03-15
              • 2019-07-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多