Exit Statuses & Return Codes
The course is part of this learning path
In this Course, you will learn how to determine the exit status of a given command. You'll learn how to make decisions in your scripts based on the exit statuses of various commands. Finally, you'll learn how to use exit statuses in your own scripts. We'll take a look at a demonstration that will give you a practical understanding of using exit statuses.
- Determine the exit status of a given command.
- Make decisions in your scripts based on exit statuses of commands.
- Use exit statuses in your own scripts.
This Course is intended for anyone looking to learn more about bash scripting and shell programming.
To get the most out of this Course, you should have some basic knowledge of the command line, but it's not essential.
Let's execute a command and check its exit status. We'll use ping here. I'm gonna use -c, which stands for count. We'll use a count of 1, which means send 1 packet. And we'll ping google.com. We see here that 1 packet was transmitted, 1 was received, and we have 0% packet loss. So to check the exit status, we'll use echo $?. And you see that we do have an exit status of 0 indicating success. Let's go ahead and try another ping command. This time I'll add the W option, which allows us to specify a timeout in seconds. So I'm just gonna set that to 1. I think the default timeout is something like 10 seconds, and I just don't wanna wait that long. So we'll ping amazon.com this time. We see this time, we get 100% packet loss. Let's look at the return code here. $? says, the return code or exit status of that ping command is 1.
Let's do something different. Let's do this, ping -c 1 amazon.com.blah. This time we get an error saying that the host is unknown. Let's check the exit code again. And this time we get an exit code of 2 from the ping command. So if you were checking to see if you could ping a host in one of your scripts, you could have your script act differently based on the return code. And remember that you can typically check the various exit statuses and what they mean for a given command by looking at its man page. Let's go ahead and do that now for ping. I'll run man ping, I'm gonna use a forward slash to start a search, and then I'm just gonna look for code. And then that's code point, we don't care about that. I'll hit N for next to go to the next instance of code. I'll just quickly read one sentence here. "If ping does not receive any replies at all, "it will exit with a code of 1."
So here you can see when it exits with the code of 1, what it means, exits with a code 2, what it means, and of course, if it's a success, it exits with a code of 0. Type Q here to get out of the man page. Let's use the double ampersand, which stands for and. This command will attempt to create a directory. And if it succeeds, then the command following it will be executed. So we'll try mkdir /tmp/jason/bak, we use $ to indicate an and, then we'll use the cp command to try to copy the etc host file into that directory. You can see that the make directory returned a non-zero exit status. We'll look at that here. And since it failed, the CP command did not get executed. Going to modify the mkdir command so that it does work. We'll use a -p to say, create the parents. So we'll go ahead and do that and execute it.
So now you can see that there was no error from the mkdir command, and the copy command with a -v says, be verbose. And it says that we copied the etc host file into the temp adjacent bak directory.
Okay, this time let's try an or command. Let's use cp -v /etc/hosts, and we'll say, copy that to tmp/bak, we'll use the double pipe to represent or. I'll run cp -v /etc/hosts / into the tmp directory. So in this example, the first copy command failed since there was no /tmp/bak directory. In that instance, since it failed, it ran the command, that follow the or symbol, the double pipe. And then so /etc/hosts was copied into /tmp. Let's see what happens when we reverse the order. So we'll do cp -v /etc/hosts / tmp/ or cp -v /etc/hosts /tmp/bak. And then, so this time, since the first copy command copying /etc/hosts /tmp/ succeeded, then the second copy command was not executed because we were using the double pipe or what's called the or.
Let's see what happens if we use a semi-colon. I'm gonna clear the screen real quick. See ls /etc/linux-release. That's going to fail for that file doesn't exist, and we'll use a semi-colon and the command host name which displays the name of the system you're working on. So even though the ls command returned an error, the host name command was executed. With a semi-colon, it doesn't matter if the first command succeeds or not, the second command will always be executed.
Let's make the ls command succeed. We'll just look at etc/hosts ; and then run the hostname command. And then you see that /etc/host file is displayed by ls. And then the host name is returned. Again, both commands were executed since we're using a semicolon. With a double ampersand, double pipe, and semi-colons, you can chain together multiple commands. It doesn't have to be just two commands. Here's an example of executing three commands one after the other. We'll do ls /etc/hosts ; hostname ; uptime command. And you can see the first line was the return from the ls command. The second line was the output from the host command. And the third line was the output of the uptime command.
Jason is the founder of the Linux Training Academy as well as the author of "Linux for Beginners" and "Command Line Kung Fu." He has over 20 years of professional Linux experience, having worked for industry leaders such as Hewlett-Packard, Xerox, UPS, FireEye, and Amazon.com. Nothing gives him more satisfaction than knowing he has helped thousands of IT professionals level up their careers through his many books and courses.