Understanding sys.exit
Some of the Piccolo commands use sys.exit
to indicate to the user whether the code ran successfully or not.
Here's a very simple example:
import sys
def my_command():
was_successful = do_something()
if was_successful:
sys.exit(0)
else:
sys.exit(1)
The number passed to sys.exit
is the exit code. In Unix, an exit code of 1
means something went wrong. An exit code of 0
means it was successful.
Using exit codes
On the command line, you can see the exit code of the last command using echo $?
.
>>> python successful_script.py
>>> echo $?
0
>>> python failing_script.py
>>> echo $?
1
You can then use these exit codes in things like if
statements.
>>> if python successful_script.py; then echo "successful"; else echo "error"; fi;
successful
>>> if python failing_script.py; then echo "successful"; else echo "error"; fi;
error
Also, exit codes are very important in build tools like Docker. If the exit code indicates a command has failed, then the build will fail.
Exit messages
If you want to indicate why the failure occured, then a string can be passed to sys.exit
, in which case the exit code is treated as 1
(i.e. a failure), and the string is printed out.
# failing_script.py
import sys
sys.exit("Something bad happened")
Let's try it:
>>> python failing_script.py
Something bad happened
How does sys.exit work?
When calling sys.exit
it actually just raises an exception. The exception is SystemExit
. It's unusual for a codebase to catch SystemExit
exceptions - but it can be done.
# refuse.py
import sys
try:
sys.exit(1)
except SystemExit:
print("I refuse!")
If we call it:
>>> python refuse.py
I refuse!
>>> echo $?
0
Are there other exit codes?
In 99% of situations, 0
and 1
are sufficient as exit codes. There are others though, but using them is rare.
import sys
sys.exit(127) # 127 means 'command not found'
Why not just raise exceptions instead?
Rather than using sys.exit
, you can just raise an exception.
# exception_script.py
raise Exception('Something went wrong')
If this exception in unhandled, and causes the program to crash, the exit code will be 1
, and a traceback will be printed out:
>>> python exception_script.py
Traceback (most recent call last):
File "exception_script.py", line 1, in <module>
raise Exception("Something went wrong")
Exception: Something went wrong
Having more verbose output may be useful for debugging purposes. However, you don't necessarily want this level of information being shown to a user if it's a known exception.
By using sys.exit
you can exit the program, and just show a message without a traceback.
Also, by using sys.exit
, it indicates clearly within your code that the intention is to stop the program, vs an exception, which is often meant to be handled.
Conclusions
So, should you use sys.exit
? In summary, here are some situations where it is useful:
- If you're writing code which will be consumed on the command line, and you want to exit the program without showing a traceback.
- If you want to return an exit code other than 0 or 1.
- To indicate clearly within your code that the intention is to stop the program.
Posted on: 22 Apr 2021
Have any comments or feedback on this post? Chat with us on GitHub.