Exit Codes#
Overview
Teaching: 10 min
Questions
What is an exit code?
Objectives
Understand exit codes
How to print exit codes
How to set exit codes in a script
How to ignore exit codes
Create a script that terminates in success/error
As we enter the first episode of the Continuous Integration / Continuous Deployment (CI/CD) session, we learn how to exit.
Start by Exiting#
How does a general task know whether or not a script finished correctly or not? You could parse (grep) the output:
> ls nonexistent-file
ls: cannot access 'nonexistent-file': No such file or directory
But every command outputs something differently. Instead, scripts also have an (invisible) exit code:
> ls nonexistent-file
> echo $?
ls: cannot access 'nonexistent-file': No such file or directory
2
The exit code is 2 indicating failure. What about on success? The exit code is 0 like so:
> echo
> echo $?
0
But this works for any command you run on the command line! For example, if I mistyped git status:
> git stauts
> echo $?
git: 'stauts' is not a git command. See 'git --help'.
The most similar command is
status
1
and there, the exit code is non-zero – a failure.
Exit Code is not a Boolean
You’ve probably trained your intuition to think of 0 as false. However, exit code of 0 means there was no error. If you feel queasy about remembering this, imagine that the question asked is “Was there an error in executing the command?” 0 means “no” and non-zero (1, 2, …) means “yes”.
Try out some other commands on your system, and see what things look like.
Printing Exit Codes#
As you’ve seen above, the exit code from the last executed command is stored in the $? environment variable. Accessing from a shell is easy echo $?. What about from python? There are many different ways depending on which library you use. Using similar examples above, we can use the getstatusoutput() call:
>>> from subprocess import getstatusoutput
>>> status,output=getstatusoutput('ls')
>>> status
0
>>> status,output=getstatusoutput('ls nonexistent-file')
>>> status
2
Once inside the Python interpreter, simply type exit() then press enter, to exit. It may happen that this returns a different exit code than from the command line (indicating there’s some internal implementation in Python). All you need to be concerned with is that the exit code was non-zero (there was an error).
Setting Exit Codes#
So now that we can get those exit codes, how can we set them? Let’s explore this in shell and in python3.
Shell#
Create a file called validate_energy.sh with the following content:
#!/usr/bin/env bash
if [ $1 -lt 0 ]
then
echo "Energy must be positive"
exit 59
else
exit 0
fi
and then make it executable chmod +x validate_energy.sh. Now, try running it with ./validate_energy.sh -10 and ./validate_energy.sh 10 and see what those exit codes are with echo $?.
Python#
The same can be done in a python file. Create a file called validate_energy.py with the following content:
#!/usr/bin/env python3
import sys
if int(sys.argv[1]) < 0:
print("Energy must be positive")
sys.exit(59)
else:
sys.exit(0)
and then make it executable chmod +x validate_energy.py. Now, try running it with ./validate_energy.py -10 and ./validate_energy.py 10 and see what those exit codes are. Déjà vu?
Assert#
An assertion is a sanity-check carried out by the assert statement, useful when testing or debugging code.
Let’s create a file called energy_assert.py with the following content:
#!/usr/bin/env python3
import sys
energy = int(sys.argv[1])
assert energy > 0, "Energy must be positive"
and then run it with python3 energy_assert.py -10.
What happens when an assertion fails in python?
Traceback (most recent call last):
File "energy_assert.py", line 3, in <module>
assert energy > 0, "Energy must be positive"
^^^^^^^^^^
AssertionError: Energy must be positive
An exception is raised, AssertionError. The nice thing about python is that all unhandled exceptions return a non-zero exit code:
> echo $?
1
We can see that assertions automatically indicate failure in a script.
Key Points
Exit codes are used to identify if a command or script executed with errors or not
Assertions automatically indicate failure in a script