In this lesson you're going to be introduced to positional parameters and the for loop here on my local
system I have a terminal open and I'm going to move into our class working folder.
And from here into our vagrant project folder this project being local users and then now I'm going
to start the virtual machine and then connect to it.
Now we'll move into the shared folder of CD4 slash vagrant and this script I'm going to name all user
Dymo 0 6 dot sh.
Of course all scripts we start with the shebang and so will give the path to the bash interpreter.
And then I'm just going to list the goal of this script or what this script does at the top here as
our Hetter
and the first thing we're going to do here is simply display what the user typed on the command line
and we can do that with the echo command here.
The variable of dollar zero is actually a positional parameter and positional parameters are variables
that contain the contents of the command line.
Before we go any further let's talk about the definition of a parameter versus an argument.
A parameter is a variable that is being used inside the shell script.
An argument is the data passed into the shell script.
So an argument is applied on the command line becomes the value stored in a parameter.
With that in mind the very first positional parameter is $ zero which contains the name of the script
itself.
You can think of this as being what the person typed in the command line to execute the script.
The next positional parameter is dollar sign one which stores the value of the first argument passed
to the script on the command line.
The positional parameter dollar sign to source the second argument dollar sign three stores a third
argument and so on.
So now let's look at the output of our script so far.
Of course we have to add executable permissions before we can execute our script so we'll do chmod
and then execute the script.
So notice how dollar signs 0 expanded to how we executed the script.
This dot board slash in the script name.
Now let's change how we call the script by providing the full path to the script so we can type forward
slash vagrant user Dymo 06 and hit enter So again when the script is called in an explicit way like
this then that is what is stored in dollar signed zero so dollar signs zero appears exactly as we have
typed on the command line here.
We're about to take a slight detour for a moment.
Bear with me here because this will all tie into positional parameters.
But again it's going to take several minutes to explain this.
So again stick with me and be patient with me.
So one thing I've glossed over is the command search path which is stored in the environment variable
path that's ph th in all uppercase letters.
Up until this point we've just been supplying either a fool or relative path to the scripts we've created.
Let's take a quick look at what the bash man page has to say about the PATH variable.
Before we move forward we'll do a forward search with a forward slash followed by Path.
We'll just keep hitting in until we get to the PATH variable.
And here it is.
It says that path is a colon separated list of directories in which the shell looks for commands.
Now if you were to look at the command execution section that it references here on your screen you'll
find that every time you type something in it the command line.
Bash first tries to find a function with that name and execute it.
Now we haven't covered functions yet but don't worry we will.
So if it doesn't find a function with that name it looks for that command and it's a list of built in
commands.
If it is a shell builtin command then it executes that.
Now you've been working with several built in commands such as Echo read type help and so on.
Now if the command you type at the command prompt or on the command line is not a function or it's not
a built in then bash searches through the list of directories defined in the PATH variable and executes
the first match that it finds if no match is found then a command not found error message is displayed.
So let's get on the main page here by typing queue.
And let's look at our path Ecko dollar path.
So in our particular case here if a command is not a function or a shell built in then bash will look
for that command first and user local bin then end user bin then it will look and user local Esben and
so on down the list.
It's important to point out that the path can be changed.
So it's not something that is guaranteed to be the same for every user across every system.
So keep that in mind by the way if you want to control the path you can do so in your script by manipulating
the PATH variable there.
Let's use a neat little command called which to tell us which command will be executed.
Let's take the head command that we've used before as an example which Ed.
So this tells us that when we type and head at the command line the program located at user bin head
will be executed the first directory in our path variable is actually user local Ben.
So let's create our own shellscript named head and place it in there we'll need root privileges to do
that.
So I'm going to create the file with Sue them user local been had and then here we're just going to
create a little shell.
Hello from my head and then we'll go ahead and save it.
We'll add the executable bit to it here.
Now let's see which head will be executed so I'll type in which head.
And it says user local bin head will be executed.
Let's use the dash option to which which forces it to print all matching executables that are in our
path.
So there are the two commands named the exact same thing.
Both are named head.
But the first one that is found is executed.
So let's go ahead and just execute this command type and head and hit enter.
Sure enough our version of the head command is executed.
Now if you want to override the default then just supply the full path so we can do that with user been
had let's say if we would just want the first line of the ETSI password file so execute that.
So this is what we've been doing all along which is explicitly defining a path to a command.
Actually to our scripts.
Let's get rid of the version of our head so we'll just you say to our M User local then head here is
one little quirk with rapidly adding and removing programs from your path.
BASH uses a hash table to remember the full path names of executable files.
It looks up the location to the executable once and then remembers it.
If you look at the type head command which will do here type read it says that head is cached to user
local bin head.
That simply means that bash will execute that command at the path without first searching for that command.
So here's the quirk.
BASH thinks that head is still located at user local been had held for we just deleted it just a few
seconds ago.
So let's execute the command and see what happens.
So if we type in head and hit enter and says user local bin had no such file or directory.
So if you run into this type of issue you can make bash forget all these hashed locations by using the
hash built in with hash dash are.
Now if we do type head we can see that it searches the path and it finds the one that really is there
and user bin.
Of course you can read about the hash a shell built in with the command help hash and there you can
see the dash r option that we use says to forget all remembered locations.
Now typically hashing is not a problem because commands don't usually just randomly appear and disappear.
During this same shell session and probably not during the execution of a shell script.
In any case it's just something to be aware of.
OK so I know that was a rather long aside but let's bring this back around to positional parameters
and specifically about dollar signs zero.
First let's prove that our script is not in our current path.
We can do that with a which command.
Which user.
Demo 0 6.
And sure enough there is no user demo 6 in our path and it lists our path there.
Use your local bin user bin and so on.
Now let's take a copy of our script and place it into our path.
By putting it into user local bin and we can do that was soooo sue for copy and then provide the path
to the directory want to copy it to and hit enter.
Now our script is in our path so we can execute it without supplying a path to the script.
Now notice what's stored in dollar sign 0.
It's the full path to the command which is user local bin l user Dasch demo 06 dot sh.
Even though we only typed in l user dasht him 06 not SH at the command line bash.
Found it in our path and executed it at that path.
And that's why the path and the file is stored in dollar signs zero.
So let's review what gets stored in dollar signs 0 in different situations so we'll do that forward
slash l user Dymo 6 so dot slashes what is executed and that's what's in dollar signs 0.
If we're explicit again and provide a full path such as the Ford site a vagrant user Dymo 6 that will
be reported as well.
However if a command is our path and we execute it like so then it reports the full path to that command.
Hey before we move on let's remove the script out of our path before we continue so will do Sea-Doo
r.m user local BNL user demos 6. sh.
There's a command called basename that removes the directory component and just returns the file name.
So let's read up about that command man base name here at the top of your screen you can see that basename
strips out the directory and suffix from filenames.
So let's see what happens when we execute this.
We'll just hit Q to get all the help page there and we'll type base name vagrant user demo 6. SH and
then it just returns just the file name without the directory portion of the file.
By the way basename isn't doing any smart checking to see if the file exists.
It just strips off the directory portion of a string that is passed to it so we can give the base name
something that clearly doesn't exist.
But it will still do its job so we can do.
Base name port slash not forward slash here.
And of course it reports here because that's the file name portion of that path to that file even though
the file doesn't exist and we can prove that with ls not here.
Sure enough there's no such file or directory counterpart.
The basename command is D-I our name so let's look at the man page for that.
This says that Dhia are named strip's the last component from the file name.
Let's get you to exit the main page and execute the command Symbol type Diyar name.
They grant all user demo 6 and hit enter and forward slash vagrant is returned because that is the directory
name or the directory portion of that full path like basename D-I our name doesn't do any smart checking.
We can give it a non-existent path and it will simply return the portion that looks like the directory
so we can do this idea or name.
This is not here.
Sure enough it returns.
This is not because it looks like the here file is in the directory.
Ford slash this forward slash is for Slash not.
But of course that file and directory that whole tree doesn't exist but Deeya our name doesn't check
it doesn't care.
It just returns the path or the directory of the file again.
Obviously this works on things that do exist but it doesn't matter to the Diyar are named command or
base named command.
Now let's use these two commands in our script.
So what we're going to do is display the path and filename of the script
in earlier lessons you use a dollar sign followed by a command that was wrapped in parentheses to assign
the output of that command to a variable that is called command substitution.
In this case we are only going to use the output of each of these commands once so we just included
them right in the echo command.
Again with this dollar sign parentheses syntax does or this command substitution syntax does is return
the output of the command.
You can assign the output to a variable or use that output without assigning it to a variable.
Either way is fine.
Perhaps assigning the output of the commands to a variable first makes for a bit cleaner code.
But I just wanted to show you that you don't have to use command substitution and variable assignment
only.
You can use it in line as well.
So let's save an execute our script and see what we get here.
The first line says you executed this command which is dollar signs 0.14 Lachelle user dasht him 0 6
that sh.
You use dot as the path to the user Dasch demo 6. sh script.
So Dot was the output of the Dhia our name command and l use your dash Dymo 6 that SH was the output
of the basename command.
So let's try executing this script in another way will provide the full path forward slash vagrant Elisir
Dymo 6. Sh.
So this time it lists Ford slash vagrant as the path and then of course the base name of the script
is l user Dasht demo 06 dot sh.
OK let's look at the bash man page real quick.
And we're looking for the special parameter section of the page here and then we'll keep hitting and
to continue to our next match and then the thing I want to point out here is the pound sign and the
pound sign it says expands to the number of positional parameters in decimal.
So a dollar sign pound sign tells us how many arguments were supplied on the command line.
Let's continue with our script here.
Menus being v to execute the most recent command that starts with the V which is a VM so I can get back
into my editor really quickly here.
So let's tell the user how many arguments they passed in.
Remember that the curly braces are optional so some people might actually just use dollar sign hash
sign.
So just be aware that if you're reading other people's scripts but I'm willing to use the curly braces
here to be very clear.
Of course here you could have simply used the dollar sign hash sign directly in the echo command similar
to what we did with the command substitution in the previous echo command.
It's really a style choice.
I just wanted to see how you can do it both ways.
So the first time I didn't use a variable this time I used a variable and then used the value of that
variable in the echo command.
So let's save our changes and then do some testing here.
So we'll just execute our script says you supplied zero arguments on the command line.
So let's just type something in after the command line or just type hello and it says we supplied one
argument on the command line and will type in another word.
You supply two arguments and so on.
So this one says you supplied three and that is giving us the proper information so it looks like Dollar
Sign hash sign works and we're all good there.
So let's continue editing our script.
Because the real goal of this little example shell script that we're working on is to generate a random
password for each user that's supplied on the command line.
We want to make sure that at least one user is supplied on the command line.
So let's do a check with an if statement.
So use if space double opening brackets space when we use a variable and between brackets here we're
going to enclose it in quotation marks and the variable we're going to look at is number of parameters.
And then we want to make sure that that's Dasch L T which stands for less than one.
So if the number of parameters is less than 1 then what we're going to do is echo a usage statement
much like you would see in a man page
instead of manually typing in the name of the script.
We can just simply use dollar sign 0 to echo back more or less what the user typed in and the command
line and then we'll tell them what they need to do.
They need to supply a user name and optionally they can supply another user name and actually optimally
they can supply even more usernames so we'll use the ellipsis there.
Now if they get to this point that means that the script did not successfully execute because they didn't
give us any people to create passwords for.
So what we're going to do is exit with a non-zero exit status and I'm just going to use one here.
Those are if statement with f I.
Now by the way let's look at the first line here again.
If the number of parameters is less than 1 then bubble block.
So here what I'm actually doing is just demonstrating something that we haven't used before just a slight
variation of Dash l t.
And where did I get that from a hopefully remember that you can get help on these tests by looking at
help test at the command line.
Of course you'll find in there that Dasch LTE stands for less than of course what is the only thing
that's less than one in our particular situation working with whole numbers here on the command line.
Negative numbers don't make sense because you can't supply negative arguments and this sorts of thing.
So obviously the the only thing that's less than 1 is zero.
So you could have said if the number of parameters equals zero then give them the usage statement and
exit.
So again either way is right.
It's just your personal preference how you think what makes sense to you.
It's style again both ways work just whatever comes to mind just use that.
Again I'm using this here so you can see some slight variations in different ways to do this.
Now let's see if our changes and start passing in varying number of arguments to our script.
We'll hit enter.
We did not use any arguments on the command line and we get our usage statement and if we check the
return code with dollar sign question mark or you can actually do this dollar sign question mark with
the curly braces then sure enough we get an exit status of one from our script.
Since it didn't successfully execute all the way.
So let's get back to our script and let's just give it one thing sure enough you supplied one argument
to let's do a b c d ok that's for arguments and I want to point out something here that we used actually
with the user add command in an earlier script which is enclosing things in quotation marks so a b c
d.
So this says that you supplied three arguments on the command line but maybe at first glance you think
that B and C are two different things but in reality because they're enclosed in quotation marks they're
treated as one argument.
Let's do this again let's see this one.
This whole thing is two.
And here is three.
So again in this instance we supplied three arguments on the command line.
Another thing you can do is simply enclose everything in quotation marks and that's fine as well.
I'm just going to use singlehood marks because that works to Dujuan.
This is to and this is theory.
So again three arguments on the command line which interprets to three positional parameters inside
the script.
There are three because they are enclosed in quotes so it doesn't split at spaces when the data passed
in is enclosed in quotation marks.
Now again the idea behind this script is that we're going to perform the same action over a list of
items.
Now this is the perfect time to use a for loop.
Let's take a second and look at the four shell built in the type dash.
A command says for is a shell keyword.
So that's a shell built in.
And so it can do is get help for.
I know there's going to be a good bit of information that pipes up to the screen so I'm just going to
pipe this.
The head command to get just the first 10 lines of output.
Hey the first line of the help says for name and words do commands.
Done the name you see in the help here is actually a variable name for each item in the list of words.
The variable name is set to that item.
Then the commands are executed and the process is repeated for each item in the list.
Let's create a loop right here at the command prompt will do for x x is the name or our variable name.
And and we're going to provide a list to do this.
Frank Lear and Doug The next thing we want to do is type in do.
Hit enter and then it's stylistically appropriate to indent so I'll just put a couple of spaces here.
Echo type hi and then refer to the variable name here.
X and yet inner and close are for loop with done.
In this example x is first assigned to Frank then the command of Echo gets executed using that variable
dollar sign X. Then the next time the loop repeats player is assigned to x.
The commands execute.
And finally Doug is assigned to x and the commands execute.
If I hit the up arrow here to pull up the command you can see the semi-colons which represent the command
separators.
So if you want to you can place this command all on one line but it's easier to read if you do not do
that.
Again it's valid syntax here.
Like you see at the Help for on your screen.
But again it's just easier to read if you put these on multiple lines when I hit enter again to execute
that again.
If you look near the top of your screen in The Help output for the four key word it says if in words
is not present then dollar sign as sign is assumed.
So let's find out what dollar sign at sign is by looking at the bash man page.
I'm going to look for the special parameters here and the main page.
Here's the section.
Now let's start with the at sign special parameter.
It expands the positional parameters starting from 1 when the expansion occurs within double quotes.
Each parameter expands to a separate word that is dollar sign is equivalent to dollar sign one dollar
sign too and so on.
Now this is nearly the same as Dollar Sign asterisk.
It also expands to the positional parameters starting from 1.
However if it's enclosed in double quotes it expands to a single word.
We don't want to treat all the parameters as a single word what we want is a list of words as they were
supplied on the command line.
That's why we're going to use dollar sign at sign and not dollar sign asterisk in our script.
By the way the use of dollar sign asterisk and dollar sign at sign are often confused.
OK let's get out of the main page here with Q and get back to editing our script.
So we're going to use a for loop will do for will supply a variable name we'll call these usernames
user underscore name and use quotations here.
Dollar Sign at sign do.
So we're going to use the command we use to generate passwords in the previous script.
So we'll do that with pass word equals well use command substitution with dollar sign followed by an
opening parentheses
and then we're going to display that user name and password.
Now obviously we can't know exactly how many positional parameters a user will attempt to supply at
the command line.
We can check for them but we just don't know in advance.
So instead of you know generating a password for dollar sign one dollar sign two dollar sign three and
so on.
Even though they may only supply two arguments for example then we're going to do is use dollar sign
at sign.
So no matter how many arguments they pass into the script it is covered by dollar sign and sign so we
don't have to guess what the user is going to do.
They can supply one to three or ten or more.
And this script is going to work just fine.
Well just supply one thing on the command line and see what happens.
So sure enough the for loop executed one time generated a password and displayed it for the user.
Let's add another user on the command line.
Let's said some more actually.
So by using the for loop in conjunction with dollar sign outside and we were able to account for everything
passed in on the command line just for demonstration purposes I want to show you what the differences
between dollar sign and sign and dollar sign.
Asterisk.
So let's just go back into our script and make that change.
So here I'm going to change the at sign to an asterisk save our changes and then execute our script
again.
So as you can see it tweeted everything on the command line as one argument.
So the for loop only ran one time and generated a password for that one argument.
Again that's the difference between dollar sign asterisk and dollar sign at sign.
Let's go back and fix our script here and change this asterisk to the at symbol here.
Save our changes and check our script.
And sure enough it runs like we want it to.
Let's take just a minute to recap this lesson and by the way we covered a lot here.
First you learned about positional parameters and how.
Dollar Signs zero expansive the name of the shelf skip and dollar sign.
One expands to the first argument supplied on the command line dollar sign to expands to the second
argument and so on.
You also learned a few different special positional parameters such as Dollar Sign pound sign which
represents the number of parameters.
Dollar Sign asterisk which expands to the list of positional parameters starting at dollar sign one
and dollar sign at sign which also expands to the list of positional parameters starting a dollar sign
one.
However the difference between an asterisk and dollar sign and sign is only noticed when enclosing them
in quotation marks.
That difference is that dollar sign Asterix treats all the positional parameters as a one string and
dollar sign and sign treats them as separate words.
We also took a slight detour in the middle of the lesson to talk about how the path shell variable is
used to store a list of Colon's separated directories that make up the command search path.
You also saw how the path variable can affect what commands get executed and why that is along the way
you were introduced to the which command as well as the base name and or name commands.
Finally you learn how to create a for loop both at the command line as well as in a script.