Scripting and automationBeginner22 min read

What Does Exit code Mean?

Reviewed byJohnson Ajibi· Senior Network & Security Engineer · MSc IT Security
On This Page

Quick Definition

When a program finishes, it tells the computer how it went by sending a small number called an exit code. A code of 0 usually means everything worked perfectly. Any other number means something went wrong, and the number can help you figure out what the problem was.

Commonly Confused With

Exit codevsReturn value of a function

A return value of a function is a value that a function passes back to the calling code within the same program. An exit code is sent to the operating system when a program terminates. In shell scripting, a function can also return a value, but it uses the same 0–255 range and is stored in $? only within the script. However, the function's return value is not the same as the script's exit code unless the script explicitly exits with that value.

In bash, a function 'myfunc() { return 5; }' sets $? to 5 within the script, but the script itself might exit with a different code.

Exit codevsProcess ID (PID)

A process ID is a unique number the operating system assigns to each running process for identification. An exit code is a number a finished process returns to indicate its outcome. PIDs are used for managing processes, while exit codes are used for reporting results.

When you run a command, you can see its PID with 'echo $$'. After it finishes, you check $? to see its exit code. They are separate pieces of information.

Exit codevsStandard error (stderr)

Stderr is a separate output stream that programs use to write error messages. An exit code is a numeric status that indicates success or failure. A program can print to stderr and still return exit code 0, or print nothing and return a non-zero exit code. They convey different kinds of information: stderr provides human-readable messages, while the exit code provides a machine-readable status.

A command might write 'Error: file not found' to stderr and then exit with code 1. Another command might write nothing and exit with code 0.

Must Know for Exams

Exit codes are a core concept in many IT certification exams, particularly those that cover Linux administration, shell scripting, automation, and DevOps. For the Linux Professional Institute Certification (LPIC-1) and the CompTIA Linux+ exams, exit codes appear in the objectives related to shell scripting and command sequencing. Candidates must understand how to use $? to capture exit codes, how to use && and || for conditional execution, and how to test exit codes in if statements. For example, a typical objective might be "Use the exit status of a command to control script flow."

In the AWS Certified DevOps Engineer and AWS Certified SysOps Administrator exams, exit codes are part of the scripting in user data and automation scripts. Candidates are expected to write scripts that correctly check exit codes to verify that services started or packages installed. For the Microsoft Windows Server certifications (like Azure Administrator), understanding %ERRORLEVEL% is essential for writing PowerShell scripts or batch files for deployment and configuration.

For the CompTIA A+ and Network+ exams, exit codes appear in the context of troubleshooting system startup issues and batch scripts. The exam might present a scenario where a script runs at startup and fails, and the candidate must interpret the exit code to determine why. In Cisco certifications (CCNA), exit codes are less central but appear when troubleshooting automation scripts used for network configuration.

In all cases, exam questions test the candidate's ability to read and interpret exit codes, write conditional logic based on exit codes, and understand how exit codes propagate in a script. A typical multiple-choice question might ask: "What is the exit code of a command that succeeds?" or "If a script runs a command and then checks $?, what value indicates success?" More complex scenario questions might present a small script and ask what the output will be, given the exit codes of the commands inside. Candidates who overlook exit codes may fail to catch subtle bugs in automated tasks on the exam.

Simple Meaning

Imagine you ask a friend to run an errand for you, like buying a specific book from a store. When your friend comes back, they don't just say "I'm back" and leave it at that. Instead, they give you a quick report.

A thumbs up means they found the book and bought it. A thumbs down means something went wrong. If you ask more carefully, your friend might even give you a number from 1 to 10 to explain what happened: 1 for "the store was closed," 2 for "the book was sold out," 3 for "I got lost," and so on.

That's exactly how an exit code works. When a computer program finishes, it sends a small number to the operating system. This number is the program's way of saying what happened. The most important rule is that an exit code of 0 means success.

Anything else means failure or a specific problem. The operating system or another program can look at this number and decide what to do next. For example, a script might run a backup program and check the exit code.

If the code is 0, the script continues normally. If the code is not 0, the script might send an alert or try the backup again. This system is simple but powerful. It lets programs communicate their results in a way that other programs and people can understand.

In the world of computers, this is how automation and scripts work together smoothly. Without exit codes, every program would have to use a different method to report success or failure, making it hard to chain programs together or build reliable automated workflows. Exit codes make the language of programs standardized and predictable.

Full Technical Definition

An exit code, also known as a return code or exit status, is an 8-bit integer value that a process returns to its parent process upon termination. The value ranges from 0 to 255, where 0 conventionally indicates successful completion and any non-zero value indicates an error or abnormal termination. The operating system kernel captures this value from the terminating process and makes it available to the parent process through system calls such as wait() or waitpid() on Unix-like systems, or through GetExitCodeProcess() on Windows.

In Unix-like systems, the exit code is set by calling the exit() function or by returning a value from the main() function in C and C++ programs. In shell scripting, the exit code of the last command is stored in the special variable $?. For example, after running a command, you can check "echo $?" to see its exit code. The shell itself uses exit codes to control flow with logical operators, such as && (execute next command only if previous succeeded) and || (execute next command only if previous failed).

In Windows, the concept is very similar. Command scripts use the %ERRORLEVEL% variable to retrieve the exit code of the last command. Programs can set the exit code using the ExitProcess() API or by returning an integer from the WinMain or main function. The range is also 0 to 255, though some applications may use signed integers where negative values indicate errors. The Windows kernel also supports a wider range through the NTSTATUS codes, but for standard command-line usage, 0 to 255 is the norm.

the interpretation of non-zero exit codes is application-specific. While 0 always means success, exit code 1 might mean a general error for one program, but exit code 2 might mean a missing configuration file for another. However, there are some conventions: exit code 1 often indicates a general error, exit code 2 is commonly used for misuse of shell builtins (like missing keyword or permission problem), and exit code 126 indicates that the command was found but not executable, while exit code 127 indicates command not found. Exit codes above 128 are often used to indicate termination by a signal on Unix-like systems, where the exit code is 128 plus the signal number (for example, 130 = 128 + SIGINT).

The use of exit codes is fundamental to scripting and automation. They allow scripts to implement error handling, conditional execution, and logging. For example, a deployment script can run a series of commands and stop at the first failure, or it can ignore minor errors and continue. System administrators rely on exit codes to monitor the health of automated jobs, cron tasks, and scheduled processes. In DevOps pipelines, exit codes determine whether a build step passes or fails, triggering notifications or rollbacks.

Real-Life Example

Think of ordering food delivery to your home. You place an order for a pizza through an app. Your request goes to the pizzeria, and they prepare the pizza. After the pizza is made, a delivery driver takes it and drives to your address. The delivery process is like a program running. When the driver arrives, they ring your doorbell. You open the door and receive the pizza. The driver's job is done. But suppose something goes wrong. The driver might arrive and find that you are not home. In that case, the driver cannot complete the delivery. They might leave a note, or they might call you. In the computer world, the driver's "report" is the exit code.

Now let's map this directly to IT. The pizza order is a command or script you run. The pizzeria is the operating system or the program itself. The driver is the running process. When the driver successfully delivers the pizza, they effectively report a "0" (success). But if the driver finds you not home, they report a "1" (failure). If the driver has a flat tire on the way, they report a "2" (another specific error). If the store is closed when the order arrives, the driver might report a "3". Each number tells you something specific about what went wrong.

Just like you, as the customer, can decide what to do based on the driver's report (for example, if the store is closed, you might order from a different store tomorrow; if the driver had a flat tire, you might wait longer for a replacement), a script can look at the exit code of a program and decide how to respond. If a backup script returns exit code 0, the log file might just say "Backup completed." If it returns exit code 1, the script might send an email to the admin with the error message. If it returns exit code 2, the script might retry the backup after waiting five minutes. This simple numerical report is the foundation of reliable automation and system administration.

Why This Term Matters

Exit codes matter because they are the universal language programs use to communicate their outcome to the operating system and to other programs. Without exit codes, automation would be almost impossible. Imagine trying to chain ten commands together in a script where each command must succeed before the next one can run. How would the next command know if the previous one worked? It would have to parse the output of the previous command, looking for error messages, which is time-consuming and unreliable. Exit codes make this instant and reliable.

For IT professionals, understanding exit codes is critical for writing robust scripts, troubleshooting failed jobs, and designing reliable automated workflows. When a scheduled task fails, the first thing a system administrator checks is the exit code. A non-zero exit code immediately tells them that something needs attention. The specific value can help pinpoint the nature of the problem. For example, in backup software, exit code 0 might mean success, exit code 1 might mean some files were skipped, and exit code 2 might mean the backup could not be completed.

In the context of software development and DevOps, exit codes determine the health of a build. A continuous integration server runs tests and looks at the exit code of test runners. If any test fails, the test runner returns a non-zero exit code, and the CI server marks the build as failed. This triggers notifications and prevents faulty code from being deployed. Exit codes are also used in package managers. If a package installation fails, the package manager returns a non-zero exit code, allowing the script to stop and report the error. A script that ignores exit codes can silently fail, leaving the system in an inconsistent state. For this reason, professionals always check exit codes in their scripts.

How It Appears in Exam Questions

Exit code questions appear in IT certification exams in several distinct patterns. The most common pattern is the direct recall question: "What does an exit code of 0 signify?" or "Which variable holds the exit code of the last command in bash?" These are usually straightforward. Another pattern is the script output question, where a short script is shown, and you must determine what gets printed to the console. For example, a script might run mkdir /tmp/test, then if the exit code is 0, it prints "Success," else it prints "Failure." The candidate must know that mkdir returns 0 on success.

A more challenging pattern is the conditional execution question. The exam may show a command chain using && and || and ask what the final result will be. For example, "cmd1 && cmd2 || cmd3", if cmd1 fails, does cmd2 run? Does cmd3 run? The candidate needs to understand that && runs the next command only if the previous one had exit code 0, and || runs the next command only if the previous one had a non-zero exit code. Another pattern involves error handling: a script may run a command, check $?, and use a case statement to handle different non-zero exit codes. The candidate must match each exit code to the correct error condition.

In troubleshooting scenarios, the exam may describe a situation where a scheduled task runs but does not complete its work. Logs show an exit code of 1. The candidate must infer the problem from context. For example, if a backup script exited with code 1, and the documentation says 1 means "insufficient disk space," then the candidate should identify the root cause. For Windows-based exams, candidates may see questions about %ERRORLEVEL% and how it differs from $?. They may be asked to identify the exit code of a command in a batch file after a network connection attempt fails.

Finally, some exam questions test understanding of exit code limitations. For example, they might ask why exit codes are limited to 0–255 or what happens when a script tries to return a value greater than 255. The correct answer is that the value is truncated modulo 256. Candidates should also know that an exit code of 128+n indicates termination by signal number n on Unix-like systems.

Practise Exit code Questions

Test your understanding with exam-style practice questions.

Practise

Example Scenario

You are a junior system administrator at a small company. Your manager asks you to write a simple script that backs up the sales database every night. The script should check if the backup command worked and send an email alert if it failed. You decide to use a bash script. The backup command is tar -czf /backup/sales.tar.gz /var/db/sales. You know that tar returns exit code 0 if it successfully creates the archive.

You write the script like this:

#!/bin/bash tar -czf /backup/sales.tar.gz /var/db/sales if [ $? -eq 0 ]; then echo "Backup succeeded" else echo "Backup failed" | mail -s "Backup Error" admin@company.com fi

You test the script by running it manually. The first time, the backup works fine, and you see "Backup succeeded" printed. The second time, you simulate a failure by removing the /var/db/sales directory. Now when you run the script, tar cannot find the source directory, so it returns a non-zero exit code. The script catches this, checks the $? variable, finds it is not 0, and sends an email to you saying "Backup failed." You receive the email and know immediately that something is wrong with the database directory. You can then investigate the issue.

This simple scenario shows how exit codes enable a script to react differently based on the outcome of a command. Without the exit code check, the script would not know whether the backup succeeded, and you might never find out that your data was not backed up. In a real production environment, this could lead to data loss. The script can be extended to check for different exit codes: for example, tar might return 1 for permission errors and 2 for file not found. You could then handle each case differently, perhaps with a more specific alert. This is exactly how professionals build robust automation.

Common Mistakes

Assuming that exit code 1 always means the same error across all programs.

Exit codes are application-specific. While exit code 1 is commonly used for a generic error, different programs assign different meanings to non-zero codes. A program might use exit code 2 for a missing file, while another program might use 1 for the same situation.

Always consult the documentation of the specific program to understand what its non-zero exit codes mean.

Forgetting to check the exit code immediately after the command runs.

The exit code is overwritten by every subsequent command. If you run other commands before checking $?, you will get the exit code of the last command, not the one you intended.

Capture the exit code into a variable immediately after the command you want to check. For example: result=$? ; then use $result later.

Believing that an exit code of 0 always means the command did exactly what you wanted.

A command can return 0 even if it did not perform its intended function. For example, a copy command might copy zero files because the source was empty, but still return 0 because no error occurred.

Always verify the logic of the command and what constitutes a success. Some commands use exit code 0 to mean 'no error,' which may still mean no files were processed.

Using exit codes without understanding that they are only 8-bit values.

If you try to return a value greater than 255, it will be truncated modulo 256. For example, returning 256 becomes 0, which incorrectly signals success.

Ensure that any custom exit codes you design are within the 0–255 range. If you need more detailed reporting, write a log file instead.

Exam Trap — Don't Get Fooled

{"trap":"In an exam, you see a script that runs a command, then checks if $? is equal to 1 to decide if the command succeeded. The question asks whether the script logic is correct."

,"why_learners_choose_it":"Learners often think that an exit code of 1 means failure, so checking if $? equals 1 might seem like a valid way to detect failure. They may not realize that many commands use multiple non-zero exit codes to indicate different failure types."

,"how_to_avoid_it":"Remember that success is always indicated by exit code 0. All non-zero values indicate failure, but the specific value does not matter for a simple success/failure check. The correct way is to check if $?

is not equal to 0, or use the 'if command; then' syntax which directly tests for zero exit code."

Step-by-Step Breakdown

1

Program invocation

The operating system starts the program as a new process. The parent process (a shell, another program, or the system init) waits for the child process to finish.

2

Program execution

The program runs its code. It may perform operations like reading files, executing commands, or computing data. During execution, the program decides what outcome it will report when it finishes.

3

Calling exit() or returning from main()

When the program is ready to terminate, it calls the exit() function (or returns an integer from main()). The value passed to exit() becomes the exit code. If the programmer does not specify a value, the compiler or runtime provides a default (often 0).

4

Kernel captures the exit code

The operating system kernel receives the exit code from the terminating process. It stores this value in the process table entry, along with termination status. The parent process can retrieve this value using system calls like wait() or waitpid() on Unix, or GetExitCodeProcess() on Windows.

5

Parent process retrieves the exit code

The parent process (for example, a shell) calls the appropriate system call to get the exit code of the child process. In a shell, the exit code is then stored in a special variable like $? (bash) or %ERRORLEVEL% (Windows cmd).

6

Conditional action based on exit code

The parent process (or script) can now use the exit code to make decisions. For example, it might continue to the next command if the code is 0, or stop and alert an administrator if it is non-zero. This is the core of error handling in scripts.

Practical Mini-Lesson

Exit codes are the bedrock of reliable scripting and automation. As a professional, you must be comfortable using them in both Unix/Linux and Windows environments. Let's walk through a practical scenario: writing a deployment script.

Suppose you need to deploy a web application. Your script should: 1) pull the latest code from Git, 2) install dependencies, 3) run database migrations, 4) restart the web server, and 5) run smoke tests. Each step must succeed before the next step runs. If any step fails, the script should stop and log the error.

In bash, you might write:

#!/bin/bash set -e # exit immediately if a command exits with a non-zero status git pull origin main npm install npm run migrate systemctl restart nginx curl -f http://localhost/health || exit 1 echo "Deployment successful"

The set -e directive makes the script exit as soon as any command returns a non-zero exit code. This is a quick way to enforce success of all steps. However, the set -e behavior can be tricky: it does not apply to commands in if conditions, loops, or certain other contexts. A more robust approach is to check each exit code explicitly and provide meaningful error messages.

For example:

#!/bin/bash git pull origin main if [ $? -ne 0 ]; then echo "Git pull failed" | tee -a /var/log/deploy.log exit 1 fi npm install if [ $? -ne 0 ]; then echo "npm install failed" | tee -a /var/log/deploy.log exit 2 fi ...

This gives you control over the specific exit code your script will return, and you can log exactly which step failed.

On Windows, the equivalent approach uses %ERRORLEVEL%. A batch file might look like:

@echo off git pull origin main if %ERRORLEVEL% neq 0 ( echo Git pull failed >> C:\Logs\deploy.log exit /b 1 ) npm install if %ERRORLEVEL% neq 0 ( echo npm install failed >> C:\Logs\deploy.log exit /b 2 ) ...

Professionals also need to know that some programs may not follow the convention strictly. For example, the rm command on Unix returns 0 even if the file does not exist, unless you use the -f flag. The cp command may return 0 even if it only copied some files, as long as no fatal error occurred. Always test your scripts in a safe environment before production use.

Another important consideration is that exit codes above 128 on Unix-like systems often indicate that the program was terminated by a signal. For instance, if a program is killed with SIGKILL (signal 9), the exit code will be 128+9 = 137. This helps in debugging why a program terminated unexpectedly.

mastering exit codes means you can write scripts that fail fast, provide clear diagnostics, and integrate smoothly into automated pipelines. This is a skill every IT professional should practice.

Memory Tip

Zero equals success, non-zero means no go, check the code before the next show.

Covered in These Exams

Current Exam Context

Current exam versions that test this topic — use these objectives when studying.

Related Glossary Terms

Frequently Asked Questions

What is the difference between exit code and return code?

In most contexts, 'exit code' and 'return code' mean the same thing: the numeric value a program sends back to the operating system upon termination. Some people use 'return code' more often for functions, but in scripting and command-line tools, they are interchangeable.

Why can't exit codes be greater than 255?

Exit codes are stored in an 8-bit unsigned integer, which can only represent values from 0 to 255. If a program returns a value outside this range, it is truncated modulo 256. This is a legacy design from Unix that remains today.

How do I capture an exit code in a bash script?

Use the special variable $? immediately after the command you want to check. For example, after running 'ls /nonexistent', you can run 'echo $?' to see the exit code. Remember to capture it into a variable if you need to use it later, because $? changes after every command.

What exit code does a successful command return in Linux?

A successful command returns an exit code of 0. This is the universal convention in Unix-like operating systems.

Can a program return a negative exit code?

In Unix-like systems, exit codes are always non-negative from 0 to 255. In Windows, the %ERRORLEVEL% can sometimes be negative, but the standard convention is to use 0 for success and positive values for errors. Negative values may appear in specific development environments but are not standard for scripting.

What does exit code 127 mean in Linux?

Exit code 127 indicates that the command was not found. It is returned by the shell when the command name you typed does not correspond to any executable in your PATH.

Summary

Exit codes are a simple yet powerful concept in computing. They are the standardized way that programs report their outcome to the operating system and to other programs. An exit code of 0 means success, while any non-zero code indicates an error or abnormal termination. The specific non-zero value can give clues about the nature of the failure, but its meaning varies by program.

For IT professionals, mastering exit codes is essential for writing robust scripts, automating tasks, and troubleshooting system issues. Whether you are in Linux administration, Windows management, DevOps, or cloud engineering, you will rely on exit codes every day. Exams like LPIC-1, CompTIA Linux+, and AWS DevOps test your understanding of exit codes, especially in the context of shell scripting and conditional execution.

The key takeaways are: always check the exit code immediately after the command runs, use conditional operators like && and || correctly, and remember that 0 is success, 1–255 are various failures. When writing scripts, always capture and log exit codes to make debugging easier. With this knowledge, you will be able to create reliable automated systems that handle errors gracefully and keep your infrastructure running smoothly.