ChatGPT解决这个技术问题 Extra ChatGPT

How to exit from Python without traceback?

I would like to know how to I exit from Python without having an traceback dump on the output.

I still want want to be able to return an error code but I do not want to display the traceback log.

I want to be able to exit using exit(number) without trace but in case of an Exception (not an exit) I want the trace.

sys.exit() stops execution without printing a backtrace, raising an Exception does... your question describes exactly what the default behavior is, so don't change anything.
@Luper It is very easy to check that sys.exit() throws SystemExit!
I said it doesn't print a traceback, not that it doesn't raise an exception.
I think that this really answers the question you asked: stackoverflow.com/questions/173278/…
Is this question specifically for Jython 2.4 or something like that? Because for modern versions of Python (even in 2009, when that meant CPython 2.6 and 3.1, Jython 2.5, and IronPython 2.6), the question makes no sense, and the top answers are wrong.

m
martineau

You are presumably encountering an exception and the program is exiting because of this (with a traceback). The first thing to do therefore is to catch that exception, before exiting cleanly (maybe with a message, example given).

Try something like this in your main routine:

import sys, traceback

def main():
    try:
        do main program stuff here
        ....
    except KeyboardInterrupt:
        print "Shutdown requested...exiting"
    except Exception:
        traceback.print_exc(file=sys.stdout)
    sys.exit(0)

if __name__ == "__main__":
    main()

There should be something like "from sys import exit" in the beginning.
If sys.exit() is called in "main program stuff", the code above throws away the value passed to sys.exit. Notice that sys.exit raises SystemExit and the variable "e" will contain the exit code.
i would suggest printing in stderr sys.stderr.write(msg)
I strongly suggest removing the lines from except Exception: to sys.exit(0), inclusive. It is already the default behavior to print a traceback on all non-handled exceptions, and to exit after code ends, so why bother doing the same manually?
@jkp - Regarding your comment: sys.exit() should be used for programs. exit() is intended for interactive shells. See The difference between exit() and sys.exit() in Python?.
M
Martijn Pieters

Perhaps you're trying to catch all exceptions and this is catching the SystemExit exception raised by sys.exit()?

import sys

try:
    sys.exit(1) # Or something that calls sys.exit()
except SystemExit as e:
    sys.exit(e)
except:
    # Cleanup and reraise. This will print a backtrace.
    # (Insert your cleanup code here.)
    raise

In general, using except: without naming an exception is a bad idea. You'll catch all kinds of stuff you don't want to catch -- like SystemExit -- and it can also mask your own programming errors. My example above is silly, unless you're doing something in terms of cleanup. You could replace it with:

import sys
sys.exit(1) # Or something that calls sys.exit().

If you need to exit without raising SystemExit:

import os
os._exit(1)

I do this, in code that runs under unittest and calls fork(). Unittest gets when the forked process raises SystemExit. This is definitely a corner case!


-1: This code is silly: why catch SystemExit just to call sys.exit(e)? Removing both lines has the same effect. Also, cleanup belongs to finally:, not except Exception: ... raise.
@MestreLion: You're free to downvote, but if you read my comment just above yours, that's only true for 2.5+. If you read all of my post, I explicitly said that the code is silly and suggested exactly what you said in your comment.
Sorry, you're right... I forgot there was a major re-structure of exceptions in Python 2.5. I tried to undo the downvote, but SO only allows me to do so if the answer is edited. So, since we are in 2012 and Python 2.4 is ancient history, why not edit it and show the correct (current) code upfront, leaving the pre-2.5 method as a footnote? It will improve the answer a lot and I'll be able to undo the downvote, and will gladly do so. Win-win for everyone :)
@MestreLion: I started editing as you suggested, but this answer really only makes sense in the context of the question and a 2.4 environment. The downvote doesn't upset me.
W
Wojciech Bederski
import sys
sys.exit(1)

I
IlliakaillI

The following code will not raise an exception and will exit without a traceback:

import os
os._exit(1)

See this question and related answers for more details. Surprised why all other answers are so overcomplicated.

This also will not do proper cleanup, like calling cleanup handlers, flushing stdio buffers, etc. (thanks to pabouk for pointing this out)


Not suitable for normal exits. This solution bypasses all the Python cleanup code!
r
rob

something like import sys; sys.exit(0) ?


@mestreLion Then why do I get Dets 06 18:53:17 Traceback (most recent call last): File "debug_new.py", line 4, in import sys; sys.exit(0) SystemExit: 0 at org.python.core.PyException.fillInStackTrace(PyException.java:70) in my console?
@Val: because you're not using a standard python console. Jython is not Python, and it looks like it (or at least its console) handles exceptions differently.
R
RCross

It's much better practise to avoid using sys.exit() and instead raise/handle exceptions to allow the program to finish cleanly. If you want to turn off traceback, simply use:

sys.trackbacklimit=0

You can set this at the top of your script to squash all traceback output, but I prefer to use it more sparingly, for example "known errors" where I want the output to be clean, e.g. in the file foo.py:

import sys
from subprocess import *

try:
  check_call([ 'uptime', '--help' ])
except CalledProcessError:
  sys.tracebacklimit=0
  print "Process failed"
  raise

print "This message should never follow an error."

If CalledProcessError is caught, the output will look like this:

[me@test01 dev]$ ./foo.py
usage: uptime [-V]
    -V    display version
Process failed
subprocess.CalledProcessError: Command '['uptime', '--help']' returned non-zero exit status 1

If any other error occurs, we still get the full traceback output.


For using sys.trackbacklimit in Python 3, see this answer.
Please send error messages to stderr, not stdout. Use this instead: print("Process failed", file=sys.stderr)
M
Miled Louis Rizk

Use the built-in python function quit() and that's it. No need to import any library. I'm using python 3.4


Please do not use quit() or exit() in your code. These functions are intended only for the interactive Python. See Python exit commands - why so many and when should each be used? You can use sys.exit() or raise SystemExit instead.
K
Karl W.

I would do it this way:

import sys

def do_my_stuff():
    pass

if __name__ == "__main__":
    try:
        do_my_stuff()
    except SystemExit, e:
        print(e)

佚名

What about

import sys
....
....
....
sys.exit("I am getting the heck out of here!")

No traceback and somehow more explicit.


B
Brian Zimmerman
# Pygame Example  

import pygame, sys  
from pygame.locals import *

pygame.init()  
DISPLAYSURF = pygame.display.set_mode((400, 300))  
pygame.display.set_caption('IBM Emulator')

BLACK = (0, 0, 0)  
GREEN = (0, 255, 0)

fontObj = pygame.font.Font('freesansbold.ttf', 32)  
textSurfaceObj = fontObj.render('IBM PC Emulator', True, GREEN,BLACK)  
textRectObj = textSurfaceObj.get_rect()  
textRectObj = (10, 10)

try:  
    while True: # main loop  
        DISPLAYSURF.fill(BLACK)  
        DISPLAYSURF.blit(textSurfaceObj, textRectObj)  
        for event in pygame.event.get():  
            if event.type == QUIT:  
                pygame.quit()  
                sys.exit()  
        pygame.display.update()  
except SystemExit:  
    pass

If you would comment the code, it would increase the quality of the answer.