LPI 010-160 – Scripting Basics Part 2
- Variables
Let’s talk a little more about variables. Now, in addition to inputting a variable as part of the arguments for a script, you can also assign the variable within the script itself using the output of another command. These variables are identified by a leading dollar sign, but they’re given a typical name that’s easier to be read, something that begins with a letter, where in the last lesson we use dollar sign $1 sign two as the first and second 2nd parameters. In this case we’re going to use dollar sign with a word to represent some other variable. These variables can be used together with normal commands as if they were command parameters as well, but the value of the variable is going to be passed to that command. Let’s take a look at this script and see how this works in reality.
Now, this script is going to check if a router is up by pinging it using the ping utility and two different variables. The first variable is dollar sign IP, which is going to come from the extracted output of the route command using grip tr and cut commands. Now when assigning a value to the variable from the output of the command, that command should be enclosed in a back tick character, which is a single quote mark. The second variable, dollar sign ping, is simply going to point to the ping program. Now when we run the script, you should see checking to see if IP address is up and then the output from the ping command which should attempt to send five packets over to the router.
If the router is up and configured to respond to pings, we’re going to get five packets returned to us and a summary information is going to be displayed to our screen. If not, there will be error messages, something to the effect of the host was unreachable. Now this script is of limited practical use and is going to give us a lot of error messages along the way because we haven’t done any kind of logic or error handling.
But that’s okay. This is just to show you the point of how these things work. Now because shell scripting is basic programming, there are errors in them called bugs. And in reality this script is only going to identify the computer’s gateway by the presence of the string UG in the router’s output line from the command route. If the computer has two routers, this thing isn’t going to work right and the script is going to misbehave because we haven’t done any logic to check for this kind of an error condition.
The purpose of presenting this script here though, is to illustrate how variables can be used and assigned and not to create a flawless working script that you can use in a production environment. Scripts which obtain information from running one or more commands are useful in configuring features that rely on system specific information or information that’s going to vary over time.
Some of the commands that we’re going to use for this purpose are things like Hostname, which is going to help us obtain the current host name of the system. The command is being run on date. This will give you the current date and time up time. This will tell you the total time the computer has been up and running. DF this will tell you how much free disk space there are and lots of other commands like these that can give you information about the system that you’re running the script on.
Now, if you take your script and you start adding conditional expressions, variables can become even more powerful because the script can perform one action if a single condition is met, or do a different action if a different condition is met. For example, let’s say I had a script that installs software and it can check for free disk space first. If you don’t have enough disk space, it’ll stop the installation and cancel the installation for you. That’s the idea of using logic in these, which we’re going to get to in a future lesson.
- Conditional Expressions
As promised, we’re going to talk about logic and conditional expressions. Now, a conditional expression enables a script to perform one of several actions depending on a particular condition or value of a variable. We do this using the if command. The if command is going to allow the system to take one of two actions depending on whether or not the condition is true or false. The conditional expression is going to be shown in brackets after the if keyword. So, for example, if f file, if that is true, the file does exist. If it isn’t, we’ll do some other action. Or maybe I want to check if a file is greater than 0 KB. Well, I can do that by doing if SF file, and if that file that is inputted there has a size greater than zero, that’s true. And I’ll take one path, or I might compare two strings and see if they have the same value. If string one equal equals string two, and if that’s true, I’ll do some action.
If not, I’ll go and do some other action. That’s the idea here. With conditionals, we’re going to test if a condition is true and then do something based on that. Now, conditionals can also be combined together with other logic and logical operators. So if I have the logical and that would be ampersand. So if one equals variable and variable two equals two, then this thing will happen. Or I can use a logical or operator which is represented by two pipes.
Now, when you combine these things, if you have the ands both sides of the operator have to be true, but if you use the or, only one side has to be true to make the whole condition true. All right, so let’s talk through this script for a second. This portion causes a script to exit if the file temp stuff is present. If we find that file and it’s greater than zero, then we’re going to do the stuff that comes after the keyword. Then this then is going to mark the beginning of a series of lines that we’re going to execute when the conditional was true. And then we have the fi, which is if backwards.
This marks the end of the if statement block. So this code may be useful if the script is going to create it and then later delete the file because the presence indicates that a previous run of the script didn’t succeed or it’s still being underway. Now, there’s lots of other conditions that we can use.
An alternative form for a conditional expression uses the test keyword rather than the square brackets around the conditional. So I can use iftestemp stuff. Again, this is just a variation on what we just looked at. Now the command is going to return a value, and that return value could be tested by the command as well as your condition. So if brackets command brackets, and you can insert whatever commands you want there, then do some things. Now if the command comes back with a true, you’re going to do some stuff. If the command comes back with a false, you’re not going to do that stuff. That’s the idea here. Now this is the idea of how we can use logic to be able to make additional smart decisions as we’re going through our scripts. Your conditional expressions can also be expanded by the use of a thing called an else clause. So it’s not just if then, it’s if then else. So if a conditional expression is true, then do this, but if not then do these other things. And then you’ll end that’s a little expression that goes a little bit further than just a standard. If this allows you to have up to pass, you can go left or you can go right, depending on the way you evaluate that conditional expression.
This is really good when doing bug testing and other things where you may want to copy a file or create a file depending on if the file exists or not or if the file doesn’t exist. That’s the idea when you start doing things like this. Now I think you’re getting the idea with the if then and else is where we have two choices. We can go left or we can go right. But what if you need more than two choices? Well then you have a couple of options. The first is you can nestle your if statements, we can do an if then if then and that. We can look that way.
So if it’s true then do option one. Otherwise do another if then statement and then take option two or else go to option three. That’d be one way to do it. But there’s actually a better approach to use and that’s what’s called case. You can use case in a script to say case word in and then give it those options. So I might say case variable in and then 12345 and each of those would be different commands that would run. You might use this in something like if you’re trying to have a menu option displayed to your user and they’re going to select which command they want to run using your script.
- Loops and Functions
So far we’ve covered commands, arguments, variables and conditional expressions inside of our scripts. But sometimes your conditional expressions aren’t enough and you need to do things multiple times. Well, when that happens, you need to use loops. Loops are going to tell the script to perform the same task repeatedly until a particular condition is met, or until that condition is no longer met. In this example script fragment, we’re going to loop playing a wave file over and over and over again, which is an audio file until it’s done.
So in this case we’re going to do 4D in LS, star, wave, do, Aplay, D, then done. Now, what this is really telling us is that this loop is going to execute once for every item in the list generated by the LS command. So every wave file we find inside that directory, we’re going to play it. Once we run out of files that end in WAV, we’re not going to be able to play any more files and our playlist is over. That’s the idea in this simple command. Now, another way to do this is using the Seq command and this can be useful for creating loops. This is going to generate a list of numbers starting from its first argument and continuing on to the last one, creating a sequence.
So for example, I might use Seq 110 and hit enter. This will generate ten lines, each one with a number between one and ten. So it’ll go 1234-5678, 910. So for a loop beginning here, we can use x in sequence one to 10 to have it loop and create ten different things going on. The value of x increments once for each iteration. So if just one parameter is going to be passed to sequence, then it’s going to interpret that number as the ending point. And it’ll always start with one. By default, if you have three values, it’s going to interpret them as a starting value, an increment amount and an ending value. So for instance, one to 10 would tell it to start counting at one increment by two until it gets to ten. And so we’d only have five loops in that case.
Now, another type of loop is the while loop, which is going to execute for as long as the condition is true. The basic form of this is while a condition happens, do the following commands and then done, you’re finished. The until loop is very similar, but the continues execution as long as its condition is false or until the condition does become true. So this is the idea with these different ways of doing loops. Now, aside from loops, there’s also a need to perform specific subtasks to be called by name from other parts of the script. This is what we call a function.
Functions are defined by placing parentheses after the function name and enclosing the lines that make up the function with curly braces, something like this my function parentheses, curly bracket, some amount of commands, and curly, bracket. Now, the keyword function may optionally precede the function name itself. In either event, the function is called by its name as if it was an ordinary internal or external command. And this allows you to jump around different parts of your script and be able to jump forward or back based on different conditions.
Functions become really useful this way to create modular scripts. For example, if a script needs to perform maybe six different computations, each computation can be placed inside of a function and then they can be called on in the proper sequence. Now, remember, functions aren’t run directly and necessarily in the order in which they appear inside the script. You can jump around based on different conditions and call them as needed. They’re only run when they’re called from the main body of the script itself. And we’ll see that as we start playing with more scripts in our command line environment.
- Exit Value
By now we should have a good idea and understanding of how a script is coded. We’ve talked about all of the pieces and parts. However, as with any script, there’s going to be a beginning, a body, and then there has to be a way to end it or exit it. In this lesson, we’re going to discuss how to set up your scripts. Exit Value now, a script’s return value is the same as the last command of the script. This means that the script is going to return dollar sign question mark. However, the exit value can be controlled and it’s possible to exit from the script at any point you want.
Using the command exit used without any options. Exit is going to cause the immediate termination of script exactly where you are, and the usual exit value of dollar sign question mark will be returned. This can be useful in error handling and aborting an ongoing operation for any reason you need. Now, if your script detects an error or if the user selects an option to terminate it, the script can also include an exit call to quit the script. Now, when you have a numeric value between zero and 255 being passed to exit, the script will terminate and return the specified value as a script’s own exit value.
This feature can be useful if you’re trying to create an error to other scripts and let them know what the problem is and why you exited the script. However, the user may also have to include extra code to keep track of all of the causes of abnormal termination, creating more work for you if you’re trying to write a really good script. Now, let’s take a look at setting aside a variable to hold the cause of the script’s termination. We’ll call it variable term cause.
We’re going to set it at zero at the start of the script, and then if the script detects a problem that’s going to make it cause a termination, we’re going to reset the value to something that’s not zero. We can use any numeric code we want, but we might be able to create different codes like one, two or three based on three different error conditions if we wanted to. Now, if we’re going to exit, we’re going to pass the variable term cause to the exit command by writing exit variable term cause. So exit, exit one, exit two, exit three, and that way we’ll know why it exited. That’s the way you can do this clean exit and be able to return error codes to your user so they’ll know why the program didn’t work right.
- Turning Commands into a Script
In this lesson, we’re going to learn a little more about scripting and start putting together some of these script components and make a couple of basic scripts. Now the first one I want to show you is this script known as directory listing sh. Now what I’m going to do is just add it to the screen so you can see it because I already typed it up for us to save us some time because it’s pretty straightforward. Now you’ll see here that the first four lines all start with a hashtag. Now that hashtag means comment. It means we’re going to ignore everything in those lines. It’s just for us, the humans, to read, but the computer is going to not pretend it’s there at all. So what I’m saying here in the first line, this exclamation bin bash is that this is a bash script. The next line tells you what the script is for.
It’s a simple script to output the files in the current directory to the screen. And you can see that I put director instead of directory because I didn’t type correctly. That’s okay. Next we have the author, my name, the date, and the date that it is today. Then you’ll see a space, and the next thing you’re going to see is the first command echo, echo your current directory is. What that’s going to do is just simply write out your current directory is and put that to the screen. Then it’s going to run the PWD command that is going to display our current working directory, our present working directory, PWD. Then we have echo the files in your current directory are it’ll, put that to the screen, and then it’s going to run the LS command. So if I want to run this command, all I have to do is make sure that that script has the right permissions first. And to do that, you’ll type in LSLA and we’ll just go ahead and list the directory. Notice on the left side, we see all those RW and X’s.
That is the permissions. We’re going to talk a lot about permissions later on in this course. But what we’re looking for specifically here right now is the fact that we have those X’s. By having those XS, it means this is an executable file. Now, if this file wasn’t executable, I’m going to teach you later how to change the permissions and make it an executable file. We use a program called change mod, and we would simply do something like change mod seven, five, five, and then directory listing. That seven, five, five equates to this pattern right here.
This Row is seven. This RX is the five, and the RX is five. That means that I can read, write and execute it. Other people can read it and execute it, and other people in my group can read it and execute it. And again, we’ll talk more about that later. But I already have those permissions set. So nothing you need to worry about right now. If we want to run this, how do we do it? Well, since it’s a bash script, we’re going to type in A and the name. And so in this case, directory listing sh. And when we run it, we’re going to see that it went through and brand those commands. This is doing the exact same thing as if I ran all four of those commands myself. If I had typed in echo, your current directory is, then what I would have gotten is this. Your current directory is.
And if I typed in PWD and hit enter, I would get Deon, training documents, scripts. If I did the echo, I would get this. And if I did LS, I would get just an LS listing, which is just this one file, just like you saw at the top of my screen when I ran LS the first time. So that’s a really basic script, and you now have an understanding of what that is and how it worked. Okay, let’s take a look at another script that I’m going to create here. So here I have one that’s called backup. Now in backup, this is a really simple script as well. In here I have bin bash backup files within a project directory, the name and the date. Now what I’m going to do is I’m going to take two inputs. These inputs are going to be one and two as I enter the file. So if I’m going to run a file such as backup shy, I’m going to give it the name of the directory I want to backup. In my case, I’m going to back up a directory known as Test Project, and then I’m going to give it a date. And that’s what the second piece is.
So something like nine 2019, meaning September 20 of 2019. When I get that, I’m going to make a directory called Test Project underscore 920 19. And in it I’m going to copy everything from Test Project, all the files and directories contained in it into this new directory. And then I’m going to put out to the screen backup of Test Project. The directory is now complete. So before I do that, let’s go ahead and take a look at our current directory. You can see I have one directory known as Test Project in there. If I look inside of Test Project, you’ll see I have two files, test one and test two. And so what I want to do when I run this command is I should end up with something known as Test Project underscore nine 2019. And inside of that will be a folder called Test Project.
And inside of that folder will be test one and test two. Essentially, this is a simple backup script. So if I go ahead and run that, it says it’s now complete. If I list the directory, I now have this new directory called Test Project. Underscore nine 2019. And if I list out what’s inside of there, you’ll see test project is and so now if I do that and then look inside of test project as well, you’ll see I have those two files, test one and test two, so I have a valid backup.
Now that is working. So again, this is a very simple script, but it shows you that you can take these routine tasks and create them inside of a script. But the real power of scripting is when you start using scripts to make decisions. All right, let’s go ahead and do one more script here and I’m going to call this one Logic. So it’s going to do Logic sh. And we’re going to go ahead and make this a pretty simple script so we could finish up here and we’re going to use Bin Bash and we’re just going to call this Simple Logic test and display.
All right? And so what we’re going to go ahead and do here is we’re going to use an if command. And what we’re going to do here is if the first argument that is entered is going to equal one, then we want to do some things. We’re just going to go ahead and echo the argument entered was one. And then we’re going to go ahead and exit that and we’re going to do Fi, which is going to end that loop. Now the next thing we’re going to do is if the first thing that entered was a two, we are then going to echo the argument entered was two.
Otherwise we’re going to echo the argument entered was not two. All right? And then what we’re just going to do there is we’re going to go ahead and type in exit and then Fi and we should have an exit up here as well. All right? So this is a very simple program and what we’re going to do is I’m going to enter a number, either one or two. If I enter one, I should get the first argument here that the argument entered was one. And notice I capitalized echo and Linux is case sensitive, so you want to make sure that’s lower case. Then if I had entered the first argument as two, I’m going to get this echo the argument entered was two.
Otherwise I’m going to get the argument entered was not two. Okay? And one more thing that I forgot is you’ll notice the one and the two there? Notice how they’re white? Well, that’s because they’re not being displayed as characters. If I’m going to enter them in, they should be characters. So I need to go ahead and quote them as characters. So now they’ll be yellow. So what we’re searching for here is if it’s number one, we’re going to get the argument entered was one. If we have number two, we’re going to get the argument entered was two. If it wasn’t two or one, we should get the argument entered was not two. And so let’s go ahead and save this and hit enter. We’ll go ahead and exit that. We’re going to go ahead and change mod the seven five for logic so it’ll be able to run. And now if I do LSLA you’ll see that it is green and we do have our executable bits there.
So let’s go ahead and type in logic and we’re going to enter one and we should get the argument entered was one. There we go. Now if we go back here and we enter two, the argument entered was two. If I put in a three, it was not two. If I get a zero, it was not two. If I have no arguments, I’m going to get an error because there’s nothing to compare it against, right? And again it’s going to error out with that was not two as well. And so what we want to do is we want to make sure that we error test for that of seeing if there was no argument. So we can do that by going back and editing our logic here. So let’s go back into logic and let’s go ahead and enter.
The first thing we’re going to check for is the number of arguments. And if it doesn’t equal one, then what we want to do is we want to give them some information usage. This script requires one argument, that is a number. And if we don’t have that, then we can exit because we’re going to just quit the program because it didn’t work for us. And we’ll end the loop of the if loop. All right, we’ll go ahead and save that. And so as we see here, we’re going to first go in and check how many arguments there are. If we don’t have exactly one argument, we’re just going to quit the script and say we need one argument. If the number entered was one, we’ll get the argument entered was one. If the argument entered was two, we’ll get the argument entered was two. And if it wasn’t two, then we’re going to get the argument wasn’t two.
So we’ll go ahead and quit this. We’ll go ahead and run this again. And now with zero arguments we get usage command not found. Why is that? Well, let’s go ahead back in here and take a look at it. Ah, because I forgot to put the echo command. See, sometimes when you do these scripts you got to think through all the use cases. And so in this case we’re just going to go ahead and put in the echo command. Now we can save it. Now we can go ahead and run it again and let’s see what happens when we run it. Now we get the usage, we get that error back because nothing was given. What happens if I give it two arguments? We should get the same thing because it wasn’t one.
Now, if it’s one, we get the argument was one. If it was two, the argument was two. If we get three, the argument was not two. If we get zero, the argument was not two. So what happens if we write in somebody’s name, the argument was not two because Jason is not two? Right? And so that’s the idea here with this logic. The whole concept in this lesson is for you to realize that you can do whatever you want inside of a script. The fact is, scripts can be really, really useful or really, really silly. In my case. I have this simple logic test here, right? And I’m just checking as the number one or two. But you can use the same type of logic to build really complex scripts. For instance, you can use our backup concept that we did earlier and create a script that is going to check if a backup file already exists for that date. And if it doesn’t, go ahead and create one.
If it does, you can skip this backup and that way you can make sure you always have a good daily backup. This is the idea of adding in these logic steps so you can test conditions using if and then and else to find out what is going on with this and let the computer do the work for you. You’re going to learn a lot more about this as you continue on in your Linux career. I just wanted to give you a quick introduction here and I challenge you to go forward and try to make some scripts on your own and see what kind of things you can come up with.