- Linux and Unix exit code tutorial with examples
- Tutorial on using exit codes from Linux or UNIX commands. Examples of how to get the exit code of a command, how to set the exit code and how to suppress exit codes.
- Table of contents
- What is an exit code in the UNIX or Linux shell?
- How to get the exit code of a command
- How to use exit codes in scripts
- How to set an exit code
- What exit code should I use?
- How to suppress exit statuses
- Further reading
- Recent Posts
- About the author
- Bash command line exit codes demystified
- More Linux resources
- Extracting the elusive exit code
- Exit status 0
- Exit status 1
- Exit status 2
- Exit status 126
- Exit status 127
- Exit status 128
- Exit status 130
- Exit status 255
- Wrapping up
- Understanding Exit Codes and Using them in Bash scripts
- What are exit codes?
- What happens if I don’t specify an exit code
- Using exit codes in your bash scripts
- Testing for exit codes
- Providing your own exit code
- Using exit codes on the command line
- More exit codes
Linux and Unix exit code tutorial with examples
Tutorial on using exit codes from Linux or UNIX commands. Examples of how to get the exit code of a command, how to set the exit code and how to suppress exit codes.
Estimated reading time: 3 minutes
Table of contents
What is an exit code in the UNIX or Linux shell?
An exit code, or sometimes known as a return code, is the code returned to a parent process by an executable. On POSIX systems the standard exit code is 0 for success and any number from 1 to 255 for anything else.
Exit codes can be interpreted by machine scripts to adapt in the event of successes of failures. If exit codes are not set the exit code will be the exit code of the last run command.
How to get the exit code of a command
To get the exit code of a command type echo $? at the command prompt. In the following example a file is printed to the terminal using the cat command.
The command was successful. The file exists and there are no errors in reading the file or writing it to the terminal. The exit code is therefore 0 .
In the following example the file does not exist.
The exit code is 1 as the operation was not successful.
How to use exit codes in scripts
To use exit codes in scripts an if statement can be used to see if an operation was successful.
If the command was successful the exit code will be 0 and ‘The script ran ok’ will be printed to the terminal.
How to set an exit code
To set an exit code in a script use exit 0 where 0 is the number you want to return. In the following example a shell script exits with a 1 . This file is saved as exit.sh .
Executing this script shows that the exit code is correctly set.
What exit code should I use?
The Linux Documentation Project has a list of reserved codes that also offers advice on what code to use for specific scenarios. These are the standard error codes in Linux or UNIX.
- 1 — Catchall for general errors
- 2 — Misuse of shell builtins (according to Bash documentation)
- 126 — Command invoked cannot execute
- 127 — “command not found”
- 128 — Invalid argument to exit
- 128+n — Fatal error signal “n”
- 130 — Script terminated by Control-C
- 255\* — Exit status out of range
How to suppress exit statuses
Sometimes there may be a requirement to suppress an exit status. It may be that a command is being run within another script and that anything other than a 0 status is undesirable.
In the following example a file is printed to the terminal using cat. This file does not exist so will cause an exit status of 1 .
To suppress the error message any output to standard error is sent to /dev/null using 2>/dev/null .
If the cat command fails an OR operation can be used to provide a fallback — cat file.txt || exit 0 . In this case an exit code of 0 is returned even if there is an error.
Combining both the suppression of error output and the OR operation the following script returns a status code of 0 with no output even though the file does not exist.
Have an update or suggestion for this article? You can edit it here and send me a pull request.
About the author
George Ornbo is a UK based human.
He is interested in people, music, food and writing. In a previous version of himself he wrote books on technology.
Bash command line exit codes demystified
Posted: February 4, 2020 |
More Linux resources
When you execute a command or run a script, you receive an exit code. An exit code is a system response that reports success, an error, or another condition that provides a clue about what caused an unexpected result from your command or script. Yet, you might never know about the code, because an exit code doesn’t reveal itself unless someone asks it to do so. Programmers use exit codes to help debug their code.
Note: You’ll often see exit code referred to as exit status or even as exit status codes. The terms are used interchangeably except in documentation. Hopefully my use of the two terms will be clear to you.
I’m not a programmer. It’s hard for me to admit that, but it’s true. I’ve studied BASIC, FORTRAN, and a few other languages both formally and informally, and I have to say that I am definitely not a programmer. Oh sure, I can script and program a little in PHP, Perl, Bash, and even PowerShell (yes, I’m also a Windows administrator), but I could never make a living at programming because I’m too slow at writing code and trial-and-error isn’t an efficient debugging strategy. It’s sad, really, but I’m competent enough at copying and adapting found code that I can accomplish my required tasks. And yet, I also use exit codes to figure out where my problems are and why things are going wrong.
Exit codes are useful to an extent, but they can also be vague. For example, an exit code of 1 is a generic bucket for miscellaneous errors and isn’t helpful at all. In this article, I explain the handful of reserved error codes, how they can occur, and how to use them to figure out what your problem is. A reserved error code is one that’s used by Bash and you shouldn’t create your own error codes that conflict with them.
Enough backstory. It’s time to look at examples of what generates error codes/statuses.
Extracting the elusive exit code
To display the exit code for the last command you ran on the command line, use the following command:
The displayed response contains no pomp or circumstance. It’s simply a number. You might also receive a shell error message from Bash further describing the error, but the exit code and the shell error together should help you discover what went wrong.
Exit status 0
An exit status of 0 is the best possible scenario, generally speaking. It tells you that your latest command or script executed successfully. Success is relative because the exit code only informs you that the script or command executed fine, but the exit code doesn’t tell you whether the information from it has any value. Examples will better illustrate what I’m describing.
For one example, list files in your home directory. I have nothing in my home directory other than hidden files and directories, so nothing to see here, but the exit code doesn’t care about anything but the success of the command’s execution:
The exit code of 0 means that the ls command ran without issue. Although, again, the information from exit code provides no real value to me.
Now, execute the ls command on the /etc directory and then display the exit code:
You can see that any successful execution results in an exit code of 0, including something that’s totally wrong, such as issuing the cat command on a binary executable file like the ls command:
Exit status 1
Using the above example but adding in the long listing and recursive options ( -lR ), you receive a new exit code of 1:
Although the command’s output looks as though everything went well, if you scroll up you will see several «Permission denied» errors in the listing. These errors result in an exit status of 1, which is described as «impermissible operations.» Although you might expect that a «Permission denied» error leads to an exit status of 1, you’d be wrong, as you will see in the next section.
Dividing by zero, however, gives you an exit status of 1. You also receive an error from the shell to let you know that the operation you’re performing is «impermissible:»
Without a shell error, an exit status of 1 isn’t very helpful, as you can see from the first example. In the second example, you know why you received the error because Bash tells you with a shell error message. In general, when you receive an exit status of 1, look for the impermissible operations (Permission denied messages) mixed with your successes (such as listing all the files under /etc , as in the first example in this section).
Exit status 2
As stated above, a shell warning of «Permission denied» results in an exit status of 2 rather than 1. To prove this to yourself, try listing files in /root :
Exit status 2 appears when there’s a permissions problem or a missing keyword in a command or script. A missing keyword example is forgetting to add a done in a script’s do loop. The best method for script debugging with this exit status is to issue your command in an interactive shell to see the errors you receive. This method generally reveals where the problem is.
Permissions problems are a little less difficult to decipher and debug than other types of problems. The only thing «Permission denied» means is that your command or script is attempting to violate a permission restriction.
Exit status 126
Exit status 126 is an interesting permissions error code. The easiest way to demonstrate when this code appears is to create a script file and forget to give that file execute permission. Here’s the result:
This permission problem is not one of access, but one of setting, as in mode. To get rid of this error and receive an exit status of 0 instead, issue chmod +x blah.sh .
Note: You will receive an exit status of 0 even if the executable file has no contents. As stated earlier, «success» is open to interpretation.
I receiving an exit status of 126. This code actually tells me what’s wrong, unlike the more vague codes.
Exit status 127
Exit status 127 tells you that one of two things has happened: Either the command doesn’t exist, or the command isn’t in your path ( $PATH ). This code also appears if you attempt to execute a command that is in your current working directory. For example, the script above that you gave execute permission is in your current directory, but you attempt to run the script without specifying where it is:
If this result occurs in a script, try adding the explicit path to the problem executable or script. Spelling also counts when specifying an executable or a script.
Exit status 128
Exit status 128 is the response received when an out-of-range exit code is used in programming. From my experience, exit status 128 is not possible to produce. I have tried multiple actions for an example, and I can’t make it happen. However, I can produce an exit status 128-adjacent code. If your exit code exceeds 256, the exit status returned is your exit code subtracted by 256. This result sounds odd and can actually create an incorrect exit status. Check the examples to see for yourself.
Using an exit code of 261, create an exit status of 5:
To produce an errant exit status of 0:
If you use 257 as the exit code, your exit status is 1, and so on. If the exit code is a negative number, the resulting exit status is that number subtracted from 256. So, if your exit code is 20, then the exit status is 236.
Troubling, isn’t it? The solution, to me, is to avoid using exit codes that are reserved and out-of-range. The proper range is 0-255.
Exit status 130
If you’re running a program or script and press Ctrl-C to stop it, your exit status is 130. This status is easy to demonstrate. Issue ls -lR / and then immediately press Ctrl-C:
There’s not much else to say about this one. It’s not a very useful exit status, but here it is for your reference.
Exit status 255
This final reserved exit status is easy to produce but difficult to interpret. The documentation that I’ve found states that you receive exit status 255 if you use an exit code that’s out of the range 0-255.
I’ve found that this status can also be produced in other ways. Here’s one example:
Some independent authorities say that 255 is a general failure error code. I can neither confirm nor deny that statement. I only know that I can produce exit status 255 by running particular commands with no options.
There you have it: An overview of the reserved exit status numbers, their meanings, and how to generate them. My personal advice is to always check permissions and paths for anything you run, especially in a script, instead of relying on exit status codes. My debug method is that when a command doesn’t work correctly in a script, I run the command individually in an interactive shell. This method works much better than trying fancy tactics with breaks and exits. I go this route because (most of the time) my errors are permissions related, so I’ve been trained to start there.
Have fun checking your statuses, and now it’s time for me to exit.
[ Want to try out Red Hat Enterprise Linux? Download it now for free. ]
Understanding Exit Codes and Using them in Bash scripts
Lately I’ve been working on a lot of automation and monitoring projects, a big part of these projects are taking existing scripts and modifying them to be useful for automation and monitoring tools. One thing I have noticed is sometimes scripts use exit codes and sometimes they don’t. It seems like exit codes are easy for people to forget, but they are an incredibly important part of any script. Especially if that script is used for the command line.
What are exit codes?
On Unix and Linux systems, programs can pass a value to their parent process while terminating. This value is referred to as an exit code or exit status. On POSIX systems the standard convention is for the program to pass 0 for successful executions and 1 or higher for failed executions.
Why is this important? If you look at exit codes in the context of scripts written to be used for the command line the answer is very simple. Any script that is useful in some fashion will inevitably be either used in another script, or wrapped with a bash one liner. This becomes especially true if the script is used with automation tools like SaltStack or monitoring tools like Nagios, these programs will execute scripts and check the status code to determine whether that script was successful or not.
On top of those reasons, exit codes exist within your scripts even if you don’t define them. By not defining proper exit codes you could be falsely reporting successful executions which can cause issues depending on what the script does.
What happens if I don’t specify an exit code
In Linux any script run from the command line has an exit code. With Bash scripts, if the exit code is not specified in the script itself the exit code used will be the exit code of the last command run. To help explain exit codes a little better we are going to use a quick sample script.
The above sample script will execute both the touch command and the echo command. When we execute this script (as a non-root user) the touch command will fail, ideally since the touch command failed we would want the exit code of the script to indicate failure with an appropriate exit code. To check the exit code we can simply print the $? special variable in bash. This variable will print the exit code of the last run command.
As you can see after running the ./tmp.sh command the exit code was 0 which indicates success, even though the touch command failed. The sample script runs two commands touch and echo , since we did not specify an exit code the script exits with the exit code of the last run command. In this case, the last run command is the echo command, which did execute successfully.
If we remove the echo command from the script we should see the exit code of the touch command.
As you can see, since the last command run was touch the exit code reflects the true status of the script; failed.
Using exit codes in your bash scripts
While removing the echo command from our sample script worked to provide an exit code, what happens when we want to perform one action if the touch was successful and another if it was not. Actions such as printing to stdout on success and stderr on failure.
Testing for exit codes
Earlier we used the $? special variable to print the exit code of the script. We can also use this variable within our script to test if the touch command was successful or not.
In the above revision of our sample script; if the exit code for touch is 0 the script will echo a successful message. If the exit code is anything other than 0 this indicates failure and the script will echo a failure message to stderr .
Providing your own exit code
While the above revision will provide an error message if the touch command fails, it still provides a 0 exit code indicating success.
Since the script failed, it would not be a good idea to pass a successful exit code to any other program executing this script. To add our own exit code to this script, we can simply use the exit command.
With the exit command in this script, we will exit with a successful message and 0 exit code if the touch command is successful. If the touch command fails however, we will print a failure message to stderr and exit with a 1 value which indicates failure.
Using exit codes on the command line
Now that our script is able to tell both users and programs whether it finished successfully or unsuccessfully we can use this script with other administration tools or simply use it with bash one liners.
The above grouping of commands use what is called list constructs in bash. List constructs allow you to chain commands together with simple && for and and || for or conditions. The above command will execute the ./tmp.sh script, and if the exit code is 0 the command echo «bam» will be executed. If the exit code of ./tmp.sh is 1 however, the commands within the parenthesis will be executed next. Within the parenthesis the commands are chained together using the && and || constructs again.
The list constructs use exit codes to understand whether a command has successfully executed or not. If scripts do not properly use exit codes, any user of those scripts who use more advanced commands such as list constructs will get unexpected results on failures.
More exit codes
The exit command in bash accepts integers from 0 — 255 , in most cases 0 and 1 will suffice however there are other reserved exit codes that can be used for more specific errors. The Linux Documentation Project has a pretty good table of reserved exit codes and what they are used for.