Why would you exit from a Bash script?
Let’s say you are writing a script…there’s one thing that is almost certain…
At some point, your script is likely to break because of unexpected conditions you might have not considered.
So, what can you do about it?
How can you exit a Bash script in case of errors?
Bash provides a command to exit a script if errors occur, the exit command. The argument N (exit status) can be passed to the exit command to indicate if a script is executed successfully (N = 0) or unsuccessfully (N != 0). If N is omitted the exit command takes the exit status of the last command executed.
In this guide, you will learn how to use the exit command in your scripts to make them more robust and to provide a great experience to those who are using your scripts.
Let’s get started.
Exit a Bash Script With Error
What can you do to write robust scripts that don’t break in unexpected ways in case of errors?
The answer to this question is: don’t forget error handling.
Instead of “hoping” that nothing will go wrong with your program, you can predict possible failures and decide how your program will react to those.
How will you handle a failure if it occurs? What will the user see?
We will have a look at how error handling works in Bash scripting (or Shell scripting in general).
These concepts apply to all programming languages even if the way error handling is implemented varies between them.
To handle errors in Bash we will use the exit command, whose syntax is:
exit N
Where N is the Bash exit code (or exit status) used to exit the script during its execution.
Different values of N indicate if the script exits with success or failure.
But, why do different exit codes depend on the success or failure of a script?
Because often other programs will be calling your script and they will need to be able to understand if everything goes well with the execution of your script or not as part of their error handling.
Let’s have a look at what exit 1 means.
What Are Exit 0 and Exit 1 in a Bash Script?
How do you exit a Bash script on error?
The standard convention is the following:
Bash exit code | Meaning |
Zero (0) | Success |
Non-zero (1, 2, 3, etc…) | Failure |
As you can see from the table above, failures can be represented with any non-zero exit codes.
For instance:
- 1 may be used if incorrect arguments are passed to the script
- 2 if the script cannot find a file it needs
- 3 if the file it needs has an incorrect format
- And so on…
You can be creative and use non-zero Bash exit codes to be very clear about the reason why your script has failed.
So, going back to the exit command.
What happens when it gets executed?
The exit command returns an exit code back to the shell.
Here’s an example…
Let’s write a script called exit_status.sh:
#!/bin/bash
echo "Exit command test"
exit 0
So, here we are passing the exit code 0 to the exit command.
How can we verify that this is actually the code passed by the script back to the shell?
We use the $? variable. Remember it, this is very important!
$? is a variable that contains the exit code of the last command executed.
And how can we read its value?
Using the echo command, in the same way, we print the value of any variable:
(localhost)$ ./exit_status.sh
Exit command test
(localhost)$ echo $?
0
Voilà here is the 0 exit code.
And what happens if we remove “exit 0” from the script?
#!/bin/bash
echo "Exit command test"
Run the script again and check the value of $?:
(localhost)$ ./exit_status.sh
Exit command test
(localhost)$ echo $?
0
We still get the 0 exit code back…
So, nothing changed…why?
Because every command we execute, including the echo command (the only command in our script), returns an exit code.
In this case, the echo command executed as part of the script is returning a 0 exit code because the echo “Exit command test” command is executed successfully.
More About The Status of the Bash Exit Command
I will show you an example of how the exit code is applied to the execution of any commands.
This is really important in your Bash knowledge and I want to make sure it’s clear to you.
Here is an example with the cat command (this applies to all commands)…
I open a shell on my computer and in the current directory I have the following files:
(localhost)$ ls -al
total 16
drwxr-xr-x 4 myuser mygroup 128 4 Jul 12:38 .
drwxr-xr-x 11 myuser mygroup 352 4 Jul 12:38 ..
-rw-r--r-- 1 myuser mygroup 10 4 Jul 12:38 test_file1
-rw-r--r-- 1 myuser mygroup 10 4 Jul 12:38 test_file2
If I use the cat command to see the content of the file test_file1 the exit code stored in the variable $? after the execution of the cat command is 0 because the execution of the cat command is successful:
(localhost)$ cat test_file1
Test file
(localhost)$ echo $?
0
If by mistake I try to print the content of the file test_file3 (that doesn’t exist), the value of the variable $? is not 0.
In this case, it’s 1, but it can have other values different than zero. This is useful to represent multiple types of errors for a given command:
(localhost)$ cat test_file3
cat: test_file3: No such file or directory
(localhost)$ echo $?
1
All clear?
If you have any questions please let me know in the comments below.
An Example of Script Failure
Now let’s modify the echo command in the simple script we have used before.
We want to run it with an incorrect syntax and see if it exits with a non-zero exit code.
Remove the double quotes at the end of the echo command as shown below:
#!/bin/bash
echo "Exit command test
If we execute the script we see the message “syntax error: unexpected end of file“:
(localhost)$ ./exit_status.sh
./exit_status.sh: line 3: unexpected EOF while looking for matching `"'
./exit_status.sh: line 4: syntax error: unexpected end of file
(localhost)$ echo $?
2
And the exit code is 2. So a non-zero exit code as we expected.
As mentioned before, remember the $? variable because it makes a big difference in the way you handle errors and you make your scripts robust.
The Bash if-else statement can also be used to write more complex logic that checks the value of the $? variable and takes different actions based on that.
Bash If Else Applied to $? Variable
Let’s see how you can use a Bash if else statement together with the $? variable.
The following script tries to create a subdirectory tmp/project in the current directory.
In the condition of the if statement, we verify if the value of the variable $? is different than 0. If that’s the case we print an error message and exit the script with exit code 1.
The else branch prints a successful message and it’s executed only if the value of $? is 0.
#!/bin/bash
mkdir tmp/project
if [[ $? -ne 0 ]] ; then
echo "Unable to create directory tmp/project"
exit 1
else
echo "Directory tmp/project created successfully"
fi
Let’s run the script:
(localhost)$ ./exit.sh
mkdir: tmp: No such file or directory
Unable to create directory tmp/project
(localhost)$ echo $?
1
The mkdir command fails because the tmp directory doesn’t exist and as expected the exit status of the script is 1.
I want to see what happens if I update the mkdir command in the script to include the -p flag that creates the tmp directory if it doesn’t exist:
mkdir -p tmp/project
Here is the output of the script:
(localhost)$ ./exit.sh
Directory tmp/project created successfully
(localhost)$ echo $?
0
This time the directory gets created successfully and the exit code returned by the script is zero as expected (the else branch of the if else statement gets executed).
Conclusion
We went through quite a lot!
Now you know:
- Why exit 0 and exit 1 are used in Bash scripts.
- How you can use the variable $? to read the exit code returned by a command (or script)
- The way to use a Bash if else statement together with the $? variable.
And now it’s your turn…
What kind of failures do you want to handle in your script?
Let me know in the comments! 😀
Related FREE Course: Decipher Bash Scripting
Claudio Sabato is an IT expert with over 15 years of professional experience in Python programming, Linux Systems Administration, Bash programming, and IT Systems Design. He is a professional certified by the Linux Professional Institute.
With a Master’s degree in Computer Science, he has a strong foundation in Software Engineering and a passion for robotics with Raspberry Pi.
Nice one..