In this lesson you'll learn how to use the case statement.
The case statement is the perfect way to make a decision based on the value of a given variable.
This is especially true when you have a specific set of values that you're looking for.
So first off I'm going to open up a terminal on my local machine and then go into our class a folder
of shell class and from there I'm going to go into the local user's directory and now I'm going to start
the virtual machine with vagrant up.
Now that the machine is booted we'll connect with vagrant S-sh and from here we can move into our shared
folder of Ford slash vagrant.
So far in this course you've been using the if statement to perform tests and to make decisions in your
scripts today you're going to learn how to make decisions using the case statement.
Now before we start writing our script let's look at the case command itself.
First off it's a shell built in.
And we know this because we can type the type command type Dasch A and specify the command which is
case and his case is a shell keyword which is a type of shell built in.
Of course since it's a shell built in you know that we can get some information on how to use it with
the help built and so will run help case.
The first line shows us the syntax of how to use the case statement.
It's all squeezed together on one line so it's a bit hard to read and I'm going to flush it out for
you in this script I'm about to write so you can see the syntax very clearly.
Also this output tells us that commands will be executed based on pattern matching.
So what you do with the case statement is compare a value to a pattern and if the value matches that
pattern the commands associated with that pattern or below that pattern get executed if the pattern
isn't matched.
Nothing gets executed.
Again this will become pretty obvious with a couple of simple examples.
So I'm going to name this script l user Dymo 0 9
will start.
All scripts like we do with the shebang.
And then let's add a comment here about what this script is going to do.
Let's start with something you already know which is the if statement by the way using the if statement
in the way we're about to use it is not really the ideal way to handle the situation.
But the reason I'm going to show you this is because one it builds upon what you already know too.
You're going to see it done this way and other scripts so it's best to know what is going on when you
see that.
And 3 it serves as a nice comparison for the better way to handle this situation which is to use a case
statement which of course will be getting to soon enough.
So with that little disclaimer out of the way let's say you want to do something if the word start was
passed in as the first argument to your shellscript you know that the first argument is stored in dollar
sign one.
So you can do something like this if
dollar sign one is equal to start then let's say we just want to echo the word starting then we close
out our IF statement and with F I that's right and quit or changes here make the script executable
and then test it out.
So that looks like it works.
So if we supply anything other than start as the first argument nothing happens in our script.
Let's go ahead and try that out.
We'll try this nothing happens.
Of course if we don't supply anything then nothing happens so again that is working as we expect it
to.
If we want to account for other cases we need to code for it.
So let's take a quick look at the help for the IF command will do help if what we need to use to build
out our IF statement to account for other strings is Elif which is short for else.
If so let's get back into our script and account for stop as an argument.
I'm going to go up here and add Elif
of dollars on one is equal to stop then we'll echo stopping if read our code from the top down.
If dollar sign one equal start then what we're going to do is echo starting else.
If dollar sign one equal stop then what we'll do is echo stopping it's pretty pretty intuitive the way
this is working out.
So let's say for changes and try it out.
Sure enough we pass and stop and stopping it's displayed to the screen.
So let's go ahead jump back in and add another left to handle status.
So here we'll go.
Elif
Alasan one is equal to status then will echo status while we're here let's handle all other cases within
else.
Let's also make this an error message by sending the output to standard error and exit with a non zero
exit status.
OK let's try this out.
So we'll do a user test demo nind at SC status display status to our screen which is what we want.
Let's pass this and restart.
And it says hey restart is not a valid option.
Please supply a valid option.
And so we can check our exit status here and sure enough it's one.
And of course if we don't display or pass anything into our script we also get the same situation we
need to supply a valid option so that our script is doing is taking an action based on the value stored
and dollar sign one in our script.
Now if you stopped right here that would be absolutely fine.
You made things work with the tools and skills that you had at the moment which is what we all do anyway
right.
But let's add to your skills and recreate this exact same functionality using a case statement.
Let me go ahead and comment out all that existing code first and then we'll go ahead and build on it
from here.
Now let's build out our case statement.
The first line consists of the word case followed by the value that you are going to check.
In our case that value is stored in side dollar sign one.
And finally we're going to end the line with the word end.
So we have case our variable and in case dollar sign one in next what we need to do is supply a pattern
followed by a closing parenthesis.
For example we want to see if dollar sign one matches the word start.
So we do this
this means if dollar sign one is equal to start then execute the code that follows.
And here's the code that we want to execute.
If you wanted to execute many commands you would simply supply them on a separate line to end the code
block use to semi-colons to finish the case statement.
Spell the word case backwards.
All right.
So let's try this out.
So that works.
Now let's go ahead.
Go back and add the other patterns that we're looking for to our case statement.
So now we're looking for the word stop and then what we're going to do there is Echo stopping to the
screen and in our code block with a two semi-colons.
And let's also look for status
so notice how we're not repeating ourselves multiple times like we did with the if statement we supply
the value that we're checking once and then all patterns we're looking to match.
So if we go back up in our script we use if dollar sign one is this LFA dollars on one is that a dollar
sign one is something else and so on.
But here in our case statement we say if dollar sign one is this that or the other then we're going
to do something based on that value.
Again it's much cleaner in my opinion than the longer if statement that we see above.
So let's make sure that this little bit of code works
a stopping argument works let's look at the status argument and that works as well.
The only thing that is left to account for is anything that does not match the strings start stop and
status.
So let's quickly reference the bash man page and get some more information on patterns as they are used
with the case statement.
So I'm going to type in man bash and I'm on a search for the case statement here SCO case.
Here we go.
It reads a case command first expands word and tries to match it against each pattern in turn using
the same matching rules as for pathname expansion.
And then it tells us to see pathname expansion below.
So that means we have to look at that section of the man page and we do that now pathname Stu XP.
Here we are really what we're looking for in this section is about pattern matching.
So let me just page down here until we get it there it is pattern matching.
So let's see here it says any character that appears in a pattern other than the special pattern characters
described below matches itself.
That's the type of pattern we have been using so far.
For example our first pattern in our case statement is S T A R T which only matches that exact sequence
of characters the special characters here are asterisk questionmark and brackets.
The asterisk matches any string including the null string said.
Another way asterisk matches anything.
I'm sure you've probably used this before right.
So for example if you want to get a list of files that end in s t you would run LS space asterisk t
s t.
Now we can do the exact same thing.
In our case statements.
Now the question mark matches any single character.
Finally the brackets are used to match any characters contained within those brackets and you can also
specify a range of characters by separating them with a hyphen.
This is all good information to know how to use questionmark in the brackets and all that.
But for our purposes right now we only need the asterisk for our current use case because we just want
to match anything else that wasn't already specified.
So we'll get on the main page with typing Q.
We'll get back to our script by starting our editor again.
So now let's match anything that is not already specified by using asterisks as our pattern.
So we'll do this matches anything.
And then we'll say supply a valid option.
Send that to standard air.
Exit our script with the non-zero exit status obviously 1 is not zero so that's going to work for us
and then we'll close out our statement here with semi colons.
Remember that your scripts are being executed from the top down.
So once a match is found the associated code block gets executed if you want to make sure something
matches Furse will then put it first in your list.
In this case we're doing the opposite and using the asterisk as a catchall to match anything that hasn't
already been accounted for and we're putting that last and our list of patterns.
So let's go ahead and try out our code we'll do Ellies user demo 0 9 start.
That works let's try stop.
Whoops I accidentally ended the line with a line continuation character but this is going to work anyway
I'll just hit enter and sure enough that works let me take that off and hit enter and that's what it
should really look like Excuse my typing mistake there.
Anyway let's keep trying.
Are other options here we want to make sure that status gets matched it does it reports back status.
Will do restart.
For example here when we pass and restarted says supply a valid option because it does not match.
Start stop status but it does match the asterisk and executes that code.
Let's say we want to modify the script a bit and allow a user to provide the word status or state and
still execute the same code.
So let's look at help case and I glossed over this earlier but in the help output here for the case
statement it says that you can use a pipe to separate multiple patterns.
So I'll go back here and then we'll change status here to status pipe.
What you can think of as an OR.
And then we'll type in the word state that we want to match.
Now if dollar sign one equals a status or it equal state the code echo status will be executed by the
way instead of using two pattern separated by a pipe symbol we could have used as th asterisk as the
Panner.
Now that would match the words status and state.
However it's not as exact because it would match other things like statu stateless static and many others.
I just wanted to share another way you could approach this but I like them more exacting option.
We went with here so let's try it out.
So will do l user Dymo 9 state and that reports a status.
And of course we can do status here as well and that works just so you know you can use multiple pipes
in your pattern.
So let's expand our script to accept dash dash status and dash dash state so we can do this dashed status
or dash dash state save our changes and try our code.
So do dash dash state first and that works dash dash status that works and if we supply something that
doesn't match like this then we fall back into the asterisk pattern and get that code block there.
Let's wrap up this lesson by talking about spacing and style
just so you know a case statement like this is really the basis of most init scripts.
For example on older Linux distributions you would run ETSI a net the S-sh D status and you would be
provided with the status of the S-sh d service.
Likewise you would stop the service by executing at CNET daddy s s h d stop and so on and so forth just
kind of like we have laid out here all the systems services were handled by a simple shell script that
used a case statement.
Anyway let's quickly talk about spacing what I chose to do when creating my case statement was to indent
each section by two spaces.
For example the patterns were indented two spaces from the beginning of the case statement.
Likewise the commands underneath each pattern were also indented two spaces from the beginning of the
pattern.
If you are for spaces type of person you can do that if you like using tabs instead of spaces.
That would be fine as well.
You can even forego the spaces altogether and have everything at the same level of indentation.
But in my opinion it's harder to read a case statement or an if statement or really anything else without
indentation so I don't recommend that approach.
If you're only executing one command following a pattern it's a common practice to keep that command
on the same line as the pattern match and to also include the closing double semi-colons on that same
line as well.
Let me create a copy of the case statement to manipulate and I'll clean it out as well.
So just
copy that below and then I'll go ahead and comment it out.
There we go while I'm here I'm going to clean up that status pattern so I'll just do this.
So let me go ahead and put these lines together here.
Notice that I'm leaving a space after the parentheses and before the semi-colon.
That's not technically required by syntax but it's a little bit cleaner in my opinion.
Now I'm not going to change the code block for our catch all pattern which includes the asterisk pattern.
It's multiple commands and it could get confusing running all those commands together plus by the way
we haven't talked about the command separator you have to use if you want to execute multiple commands
on a single line and we'll be getting to that later.
Now if you look at this case statement it's a fairly compact yet it's pretty clear.
It's pretty easy to read down the list of pattern start stop status and then the asterisk for everything
else.
So let's make sure that this newly formatted case statement still works.
OK it still works with start.
Does it work with Stop it does.
Let's give it nothing which should match the asterisk pattern and sure enough it tells us to supply
a valid option so that still works even though we formatted it slightly differently before we wrap things
up.
I wanted to point out that you can use the case statement in conjunction with values other than dollar
sign 1.
For example you could prompt the user for input and use a case statement to make a decision based on
that input.
You could create a simple menu system that way for example.
Well that brings this lesson to a close in this lesson you learned how to use the case statement.
If you find yourself writing a large if elif statement comparing different values against the exact
same variable.
Consider using a case statement in its place.
You can check the contents of a variable against the list of patterns that you specify.
You can do exact matches by specifying the exact string that you're looking for.
You can also perform matches with patterns that include asterisk question marks and brackets to perform
the same set of actions against multiple patterns separate each pattern with a pipe.
Remember to end each pattern with a closing parenthesis and the code block for a given pattern executes
until it encounters two semi-colons.