Exit Codes
Last updated on 2025-06-18 | Edit this page
Overview
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
One very important, foundational concept of Continuous Integration / Continuous Deployment (CI/CD) tooling is exit codes. These signal to the many CI/CD tools if a job is successful or failing. The connection between exit codes and CI/CD pipelines is programming language agnostic and useful for any project understanding and debugging CI/CD issues.
Start by Exiting
How does a general task know whether or not a script finished
correctly or not? You could parse (grep
) the output:
OUTPUT
ls: cannot access 'nonexistent-file': No such file or directory
But every command outputs something differently. Instead, scripts also have an (invisible) exit code:
The exit code is 2
indicating failure. What about on
success? The exit code is 0
like so:
OUTPUT
0
But this works for any command you run on the command line! For
example, if I mistyped git status
:
OUTPUT
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.
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:
Printing Exit Codes via Python
To enter the Python interpreter, simply type python
in
your command line.
Once inside the Python interpreter, simply type exit()
then press enter, to exit.
PYTHON
>>> from subprocess import getstatusoutput
>>> status,output=getstatusoutput('ls')
>>> status
0
>>> status,output=getstatusoutput('ls nonexistent-file')
>>> status
2
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 python
.
Shell
Create a file called bash_exit.sh
with the following
content:
and then make it executable chmod +x bash_exit.sh
. Now,
try running it with ./bash_exit.sh hello
and
./bash_exit.sh goodbye
and see what those exit codes
are.
Ignoring Exit Codes
To finish up this section, you will sometimes encounter a code that
does not respect exit codes. This can be very annoying when you start
development with the assumption that exit status codes are meaningful
(such as with CI). In these cases, you’ll need to ignore the exit code.
An easy way to do this is to execute a second command that always gives
exit 0
if the first command doesn’t, like so:
The command_1 || command_2
operator means to execute
command_2
only if command_1
has failed
(non-zero exit code). Similarly, the
command_1 && command_2
operator means to execute
command_2
only if command_1
has succeeded. Try
this out using one of scripts you made in the previous session:
What does that give you?
Overriding Exit Codes
It’s not really recommended to ‘hack’ the exit codes like this, but this example is provided so that you are aware of how to do it, if you ever run into this situation. Assume that scripts respect exit codes, until you run into one that does not.
Key Points
- Exit codes are used to identify if a command or script executed with errors or not
- Not everyone respects exit codes