Check out a free preview of the full Introduction to Bash, VIM & Regex course:
The "Exit Codes, Operators, and Subshells" Lesson is part of the full, Introduction to Bash, VIM & Regex course featured in this preview video. Here's what you'd learn in this lesson:

James illustrates an exit code, which is a code returned to a parent process by an executable. If the code is successful, the exit code is 0. Next James demonstrates the &&, ||, and ; operators. Then James demonstrates a subshell, which is a subprocess or child process of the parent shell.

Get Unlimited Access Now

Transcript from the "Exit Codes, Operators, and Subshells" Lesson

[00:00:00]
>> James Halliday: I noticed another thing that I hadn't put into the notes, which we talked about a little bit already, which is exit codes and chaining together commands in different ways. So, try to put that into the notes after this, so whenever you're in a command, there's this notion of the exit code.

[00:00:22] So if you're in a command and it's successful, the exit code is gonna be zero. You can read out what the exit code is by this special variable called dollar sign question mark. And so it's zero if the command was successful, if the command fails like I try to list out a file that doesn't exist, for example, then the exit code is non zero.

[00:00:49]
>> James Halliday: There are different kinds of operators that you can use to kind of make use of these exit codes. So, we used the while command earlier and how the while command works is whatever command you put as an argument to it will be run and,
>> James Halliday: So, while this command is successful, it's gonna do something else.

[00:01:19] So we can create an example of this. So why don't we do while ls cool.txt; do date; sleep 1. So every second should print out the date, so long as cool.txt exists. So I'm gonna go ahead and create that with another command called touch. Touch is a very simple command that just creates a file.

[00:01:40] It also modifies timestamps, but whatever. So now, here we go, the file exists. So the LS command is gonna exit with an exit code of zero, successful. If I remove that file, now the y loop terminates because the file doesn't exist anymore. There's actually a better way to do this particular thing which is to use the command called test.

[00:02:04] It takes a bunch of options. One is called -f, which just tests if a file exists. So then you don't get this message like firm LS cannot access. The test is a bit quieter, so it's good if you're expecting a file to exist or not. A little bit more.

[00:02:21]
>> James Halliday: So if I do the same thing, the first time I run it, the file doesn't exist yet, so it's just gonna exit right away. If I create that file, now the exit code of test is gonna be, I can show you by running that here. The exit code is zero because it exists.

[00:02:40] And delete it. The exit code is non-zero because the file no longer exists. There's also a command called until which is just the opposite of while. As long as that command has an exit code that is non-zero, the command will run. It just flips it around a little bit.

[00:03:11] The other thing you can do with exit codes is you can chain together commands depending on whether something was successful or not. Good example of this is if you only wanna do subsequent commands if the first command succeeded or not. So if you have something that kind of takes a few steps to do.

[00:03:34] If it fails somewhere in the middle, you don't wanna keep going with the steps that kind of assume the previous steps. Maybe, they operate on some files that were created by the preceding steps. So to build that kind of a pipeline you can use the && character. How this works is So say we use just, for example, the test-f command, which is going to be successful.

[00:03:58] You can put another command after it. Maybe I'll do test-f cool.txt. You can put in another command after a double ampersand. And then, if the first command was successful, meaning its exit code is 0 Then the second command will run. So in this case cool.txt does not exist so it should not be successful.

[00:04:23] So here, I have this echo whatever. So we should not see the message whatever at first. And then if I make the file cool.txt. Now, that command tuns so we see the message.
>> James Halliday: Related to the double ampersand percent is the double pipe character which is the ore operator.

[00:04:49]
>> James Halliday: So, the ore operator will not run the second command if the first succeeded. So it's kind of like the opposite of the double ampersand command. This is sometimes known as short circuiting. Cuz if you have a logical or operation, if the first thing was true on the left, you don't even care whether the second thing is true because you know that the results is going to be like true.

[00:05:22] So that's kind of where this idea comes from. So now it's gonna work just the opposite way as using the ampersand. So in this case cool.txt exist. So we don't see the message. If I remove the file, now we do see the message. It's the opposite behavior. The final operator is the semi colon and semi colon is just like a, with new lines is always going to execute the next command.

[00:05:53] The command doesn't even have to exist. If you do a semicolon, the next thing is always going to run. If you did that with &&, it wouldn't run the next thing, if you did it with, || it would run the next command.
>> James Halliday: Okay, so that's, you have a question?

[00:06:16]
>> Speaker 2: Is there something like a ternary operator where it's like if it's true, then it does the first one, if it's false, it does the second one?
>> James Halliday: I don't know of one, but I bet there is. But you'd have to dig for it. [LAUGH]
>> Speaker 2: Yeah.
>> James Halliday: I don't know off the top of my head if there is one.

[00:06:30] But
>> Speaker 2: I'm sure you can also build one.
>> James Halliday: Yeah, I think you could build it out of or and and operations.
>> Speaker 2: Right.
>> James Halliday: Probably. Or there's also an if statement that you could use to do this kinda stuff. So there's if else as well. So if, why don't I just go ahead and show that?

[00:06:50] So, all right it's usually more useful to do things like if in a shell script but I will just do it on the command line right here. So, if we have a if test -f cool.txt, we do a semicolon nd then then similar to kind of the do syntax with the while loop that we just saw.

[00:07:11] Then it's like echo okay else echo, or I'll just say echo true false. That'll be good. And then you do FI at the end instead of done, which is burned from Algol 68 of all things. I was reading about yesterday very old programming language. So the file does not exist.

[00:07:43] Then if I create the file it does exist. So that's what I would probably use in for like the kind of if else case. Just do an if statement.
>> James Halliday: I don't think I have anything in the notes about sub shells but, sub shells are the best thing.

[00:08:02] So, any time you can have these kinds of little one-liners, you can put parentheses around them. And you can do things like, so when you put parentheses around it, it sorts of treats it, or maybe they're called subcommands. Anyways, it sort of treats it like a program, like a Separate program.

[00:08:24] So you can do things like echo the status code for example. So like if I exit 1 then it should be an exit code of one, very simple. If you type exit normally, it's just gonna like close your terminal but because we're instead the sub commands with parentheses it like of like it have it's own It has its own sense of standard out and standard error as well.

[00:08:49] So if you have a program, so normally you can do things like redirect standard error to standard out. So that message is actually printed to secondary thing called standard error. So if you try to pipe that, it's,
>> James Halliday: Let's see. If I try to redirect that to dev null, which is a way of throwing the data away, I still see the message, which is annoying, right?

[00:09:17] Because what if you don't want to see anything? So there's a little trick you can do where you do 2, which is the File descriptor code for standard error and you redirect to and &1, why? I don't know that's just how it is and now.
>> James Halliday: Hang on, right this is actually a little bit complicated it has to come after.

[00:09:41] All right and then it discards it. What's cool though is if you have a subcommands, like suppose that you only want to see the standard error, you don't actually want the standard out, you can sort of like juggle around the subcommands in such a way to make that work.

[00:10:01] Which I'll not show because you sort of have to like concoct a reason to do that, but I've had to do that. Like enough times that. Okay, so that's sort of what double ampersand means, what the double or character means, and how semi-colon works, and what exit codes are.

[00:10:20] And when you might use them with the test command and if else. Let's see if there's any questions? Cool, someone has a littler ternary there. Yeah, I guess you can just chain and and or commands, and it basically does ternary. So that's how you can build that feature.