In this lesson you'll learn how to process command line options using the shell built in getups if you
want your shell scripts to behave like other Linux executables.
You're going to want to allow users to specify options that change the behavior of your scripts.
For example you might want to give the user of both option where the user sees a lot of output from
your script.
Or maybe you want to give them a quiet option where your script does its work silently and then only
reports if it has an error.
Probably one of the first commands you learn how to use on a Linux system was less right after learning
that ls lists files you probably learned about the dash l option which makes LS list files in a long
listing format giving you more information using get ups helps you not only provide such functionality
in your scripts but also helps you to conform to Linux programming conventions.
Knowing what you've learned so far you could use an if statement or a case statement to check for individual
options like Dasch L or dash A.
However if you want to allow the user to combine those short options together so that Dasch L-Space
Dasch a performs exactly like a dash L.A. or dash a.
Doing that with a simple case statement is actually kind of hard.
And get UPS handles this and other little gotchas when working with options.
And that's one of the reasons why we're going to use it here today.
OK let's get to it.
I've got a terminal open on my local machine and I'm going to go into our class folder of shell class
and then we're still working on the local users vagrant project and I'm going to bring up the system
with vigor and up.
Hey let's move into our shared folder of forward slash vagrant.
Now first off getups is a shell built in and we can tell this by running the type command against it
will do type Desch a g e t o p t s.
And sure enough it is a shell built in.
As you already know I recommend using shell built ins whenever possible because it makes your script
more portable.
That's one of the reasons why we're going to be using get ops.
There is a very similar command called Get Opt. that singular that you might see in some older scripts.
Get up is an executable on the file system so it will do type Desch a get up and sure enough that is
located on this particular system in user bin.
Get up Get up.
Is very similar to get ups but it has its limitations in its own set of unique quirks.
If you're interested in learning more about it or you end up having to dive into the details of it at
some point because you run across a script that has to get up in it then just read the man page on get
up and you'll be well on your way.
Now let's get some help on the get UPS built in function here.
So do help get ops.
Actually let me pipe that to less so we can actually read what it says here on the screen and its usage
is.
Get ups Opt. string name.
And as we know anything in brackets is optional so you have an optional argument there on the end.
Now instead of me reading this entire Help section to you just let me quickly summarize it and we'll
start using it right away.
So the Opt. string is something that you are going to provide.
These are the options that your script is going to recognize and accept.
It's just a series of letters that are going to be your options.
If you want to make an option mandatory then follow that letter option with a colon.
Next you're going to provide a name.
It's a variable that's going to get populated with an option.
That way you can do something based on that option because you have no idea what a user is going to
do and how many options they may try to supply.
You'll need to use get ups in a while loop get ops returns 0 as long as it finds an option to process.
Otherwise it returns one which will cause the while loop to exit.
Finally get ups parses positional parameters by default but you can make it parse.
Something else entirely by providing it with an argument at the end.
All right so let's write a script that uses get ups.
Let's make this script generate a password.
Let's also give the users some control over what happens here with a script.
We'll let them specify a password length with a dash l option and whether or not to use a special character
with the dash s option
and let's let them control the verbosity or level of output that is going to be displayed to the screen.
Because a user can optionally specify a password length.
Let's go ahead and set a default value for that
will use the variable length and we'll send it to 48 characters long this default value will be overridden
with whatever the user provides.
If they decide to specify a password length with the dash l option which we're going to account for
in just a second.
Now what we're going to do is use a while loop in conjunction with the get ups command in the while
loop we're going to use a case statement to do something based on the option provided.
This is the structure you're going to see and use when processing command line options.
All right I'll just start the while command here will do while yet.
Ops This is our OP string.
And this is our variable name.
Now remember we have to tell.
Get ups what options are valid here.
We're going to allow the dash via option the dash l option and the dash s option.
That's why we have the characters Violette's and the OP string if you want to make an option have a
mandatory value although that option with a colon by using the L colon as we are saying that the dash
l option must be followed with an argument of its own for this script.
We want the user to supply a link to the dash l option.
Now we're going to use a case statement to process our options.
When an option requires an argument getups places that argument into the shell variable opt ARG here
were signing that arguments value to the link variable.
If the user were to execute our script with Dash L4 then four will be assigned to opt Argin here.
We're assigning that value of 4 into the length the variable that we'll be using later on in the script.
By the way you could have used an asterisk as the catchall pattern in the case statement but get obs
is giving us a single character option at a time.
So I decided to use the pattern for a single character which is the question mark.
We'll come back to this section in the second.
But first let's see what we have so far.
OK that's dash V for the verbose option and that seems to work.
That just doesn't display any output because we didn't tell it to.
Let's see what happens when we run it with Dash L we get an error.
So get ups is taking care of this situation for us it's saying hey this option requires an argument.
So we'll go ahead and give it an argument and that looks good.
Again we didn't print anything or do anything in that case statement.
So this is expected behavior at this point.
So let's do this given an option that is invalid.
So we'll get that here and it says illegal option X..
OK so this is a good basis for our scrip.
Now let's jump back in and continue building this out.
Instead of echoing in valid option to the screen and exit teaching I want to teach the user how to use
this script.
In theory I could place that code right in the case statement.
However I think it's going to be several lines long so I'm going to put it into a function.
This makes the case statement easier to read.
Again this is a pure judgment call you can do this without a function if you want to.
So here I'm going to do this.
I'm going to get rid of this and instead I'm going to say usage.
Now we have to go back to the top of our script and define this usage function.
Again it's a best practice to place all your functions at the very top of your script.
So I go up here and I will say usage will do this here.
So here we have a function that displays the usage we're modeling our usage here after man pages and
the help built in command.
We're putting optional options within brackets and so on and so forth.
We're giving some information about what those options are and then we're going to exit the script with
the next status of one because if they've ended up here that means they've used an invalid option or
something like that.
So we're going to exit with a non zero exit status.
So let's try this out.
Our user demo 11 dash X and it says a legal option X that's coming from get ups and then what has happened
is our catchall of the question mark in our case statement has been executed or that has been matched
and the code underneath it which is usage causes us to execute the code in the usage function that we
declared and then we get this information to our screen.
Now our exit status should be one because that is what's going on in that function.
So let's just check it real quick and sure enough the exit status is one.
If we're in verbose mode we want to tell the user everything that is happening in the script.
So let's do a little check.
Let's go down here after the case statement and the while loop and we'll do this
so this is the type of check we need.
But if we need to check the verbose variable every time we want to display something to the screen that
is going to be a lot of duplicated code and repeated work.
So in the spirit of keeping things dry don't repeat yourself.
We're going to move this check into a function so I'll just actually delete this and move it back up
to the top here.
So what we'll do is call log.
Now I'm not the biggest fan of that name because we're not actually going to write anything to a log
file and this particular script but it works for demonstration purposes here gives you an idea of what
is happening or what this function does.
Now perhaps we could have named this function something like local echo or display or say or probably
something that I like better or something more verbose like send to standard out or something else that
you dream up.
Anyway I'm going to go with log here for now.
It's going to work for our purposes.
So what are we going to do is have a local variable called message and we're going to assign that any
anything that has been passed into this function.
Now we'll just do our check here.
If verbose is true then we'll echo whatever that message is to the screen.
OK.
And that wraps up our little function.
So now that we have a function we need to call it instead.
So we'll go down to the bottom of our script here.
And instead of doing an echo we'll do log generating a password.
Also we can replace the echo command with the log function for the initial verbose message above.
So we have echo here.
So all we can do the same thing or just log here to be consistent.
Kate let's see if this works so we'll do our script name here and we'll do a dash of the option.
Hey sure enough verbose mode gets printed to the screen generating a password also gets displayed to
the screen.
Well let's see what happens if we don't use for bus mode.
OK.
Nothing gets echoed to the screen even though we had that log that says generating a password.
Well that log function checked a verbose mode was set and it wasn't.
So it did not display it to the screen so this is doing exactly what we wanted to do.
So now it's actually generate a password.
I just stole that little line of code from one of our earlier lessons.
The main thing to point out here is that we're using the variable length we set the default value to
be 48 but a user can change that with a dash l option.
Now let's see if we need to append a special character to the password or not and we can do a simple
check with an if statement.
Again the couple of lines of code here that do the actual work were covered in an earlier lesson.
Let's tell the user that we're done and then just give them the password
and wanted to point out that the reason I'm using the echo statement directly to display the password
is that I want to display that password no matter if the verbose mode is on or not.
So let's check our work at the command line here.
OK we get a random password that's 48 characters in length by default so that looks good.
Let's append the dash s and sure enough you can see that a special character is appended to the end.
Let's do this with verbose mode.
Sure enough now it says verbose mode is on regenerating a password we're selecting a random character.
We're all done and here's your password so that's very very wordy or very verbose so obviously the verbose
mode is doing its job.
Now by the way something that get ups handles for us here is a convention where you can not only do
s v but you can do Dasch the S which is the same as dash of the dash s or dash dash V.
OK now let's try specifying a length so we'll do dash l dash 8 and sure enough we get a password that
has eight characters in it and lets also combine this with a dash s option to append a special character.
All right so we have a password that's 8 in length plus one plus a special character.
Again we could go back and really revise the script and get specific and really make sure that if we're
adding a special character that we chop off a character from the password before it is actually truly
eight characters.
Again I'm of the mind that this probably is close enough this gets us like 90 percent of the way there
without going in and doing some even more complex work that in the end probably truly doesn't matter.
For our practical use case here.
OK so at this point we could really stop here because our script does exactly what we want it to do.
However I want to show you how to handle additional command line arguments beyond the options that you
are taking care of with get ops in order to do that we need to talk about arithmetic expansion and arithmetic
evaluation.