The While Loop, Infinite Loops, Shifting, and Sleeping
Start course
1h 37m

In this course, you'll learn how to generate some random data, including how to automate the process of generating a random password. We'll then look at a range of shell script statements and parameters including positional parameters, arguments, for loops, special parameters, while loops, infinite loops, shifting, and sleeping. Finally, we'll walk you through how to add users to a Linux system.

This course is part of the Linux Shell Scripting learning path. To follow along with this course, you can download all the necessary resources here.

Learning Objectives

  • Automate the process of generating a random password
  • Learn about a variety of statements and parameters that can be used in shell scripting
  • Learn how to add a user to a Linux system

Intended Audience

  • Anyone who wants to learn Linux shell scripting 
  • Linux system administrators, developers, or programmers


To get the most out of this course, you should have a basic understanding of the Linux command line.


In this lesson, we'll continue exploring positional parameters, and you'll also learn how to create a while loop. Of course as always, I'm going to start a terminal on my system, and move into the folder for the class and then move into the folder for the project that I'm working on and then start the virtual machine, and when it comes up, we'll connect to it. Now that we're connected to our virtual machine, we'll move into the shared folder /vagrant. And this script I'm going to name Of course we're going to start out our script with a shebang and give it a path through the bash interpreter. I'm also going to provide a little header here, demonstrate the use of the shift command, and while loops. In a previous lesson, you learned that the first positional parameter of $0 contains the name of the script itself while $1 stores the value of the first argument passed to the script on the command line. $2 stores the second argument and so on. We never actually use $1, $2 directly in that lesson, so let's do that now so you get a chance to see how that works, and how they behave in different situations. So let's just display the first three parameters. We'll use an echo statement here. And I'm just going to copy and paste here. I'm going to add an echo statement here which is just going to print a blank line. Now I'm going to save the changes to the script and then exit. Since this is the first time I'm executing this script, I need to make sure that it has the proper permissions. Now I'm just going to execute the script without any arguments. So there are no arguments and that means there are no values to store inside the script as positional parameters, so of course, parameter 1, 2, and 3 are blank. Let's pass in one parameter and see what happens. We'll just call it with an argument of apple. So now $1 is assigned the value of apple and that gets printed. So let's do this again with bread, gets assigned to $2 and let's say candy. So now $1 is apple, $2 is bread, $3 is candy, and we can directly access those and use those in the script by using $1 and so on. If we were to add more command line, for example, another word here, let's say dumplings, then that is stored in $4, but we didn't account for a user entering $4 so that presents a challenge. And so that's why we're going to use things like for loops, and while loops to handle command line arguments in many cases. Next in our script, we want to loop through all the positional parameters. In the previous lesson, we used a for loop to do that, but this time let's use a while loop. So let's look at the while command, what type is it. Whether it's a shell keyword or shell built in. So that means we can use help against that command, help while and hit enter, to get some information about it. Now it says while commands, do commands, done. This executes commands as long as the final command in the while commands has an exit status of zero. You can think of this as being while true do. While the condition that is being tested for is true, then the commands will execute. This means that during the while loop, you'll want to change the thing being tested for in some way so that the condition eventually evaluates to false, or you'll end up in an infinite loop. Let's create a while loop here at the command line. Let's use a variable called X, we'll assign that the value of 1. We'll use while, we're going to use double brackets just like we did in the for loop. Now we're going to use a conditional expression, we're going to test if $X is equal to 1, if that is true, then what we're going to do is echo, this is the value of X, and then simply echo the value of X. Now we're just going to manipulate the variable X in some way. We'll just change it to 7 here and then type done. And so what happens is, while in that conditional expression, X=1, if that's true and it is, then it executes the code block between do and done. So it echoes what you see on your screen and then X is changed to 7. Now the while loop executes again, so it says now is X=1. Well, it is now false because X is 7 so it doesn't execute the commands below and the while loop exits. This loop isn't really practical, but it demonstrates changing a variable that is being tested against in the conditional expression of the while loop. By the way, if the conditional expression never evaluates to true, then the commands in the while loop will never get executed. For example, right now the value of X is 7. So we can do echo $X, sure enough it's 7. And if we execute the while loop again, I'll just back up here a couple of commands and hit enter, nothing happens because X-eq1 evaluates to false. When you're learning about the while loop and doing some experiments on your own, you're going to end up creating an infinite loop at some point it's just going to happen. So let's do it on purpose and show how easy it is to break out of it. Before we do that I wanna introduce you to the true command. Its only job is to return and exit status of zero. So what type of command is true? It is a built-in as well as a program. Of course we can get help on a built-in by using help true. And it says it just returns a successful result. The exit status is that it always succeeds. Now I happen to like the description of the executable better. So let's look at the man page for user being true. So we'll just do man true, and it says, do nothing successfully. I just love that definition. So in any case, no matter what happens with true, it just returns an exit status of zero. So we can test this. We'll just type the true command, and then we can look at echo $?, sure enough it returns zero. If we do true blah, it doesn't really matter because again it just always returns zero. Before we create our infinite loop here, let's look at just one more command called sleep. Sleep happens to be an executable program on the system, it's not a shell built in. So we'll use the man page to learn more about sleep. So sleep simply delays execution for a specified amount of time. You can use sleep followed by a number and a suffix, and that suffix can be s for seconds, m for minutes, h for hours or d four days. So sleep does what it sounds like, it just sleeps. It doesn't do anything for a specific amount of time. So I'll hit Q to get out of the man page here, and then just do sleep for one second. Nothing happens and you've returned to the command line. Of course, that is the same as sleep 1s, and you can even do half a second or portions of a second. So let's do this, sleep for just a half a second and hit enter. Now let's build our infinite loop, so we can do while and we'll test for true, true always returns zero and exit status of zero, so it's always true. So this is going to never change this, while loop is going to run forever. So we'll just do while true do, then what we're going to do, is just simply echo a random number. And now we're going to sleep for one second and then we'll close out our while loop here with the syntax of done. Now, when we hit enter, echo gets executed it executes and displays a random number, sleep rest for a second, if you will, and then the loop repeats because while true always evaluates to true. So this will just go on for forever. Now to break out of this loop, all you have to do is hold down the Control key and type C. So Control + C sends an interrupt signal to the command which makes it stop. Now, this isn't something unique to the wall command, you can use this to stop any command running in the foreground. For example, if you execute sleep and wanna interrupt it and return to the command line sooner, you can use Control + C there as well. So let's say we give sleep the instruction to sleep for 10 minutes, and then we decide we don't wanna wait that long, so we'll just go ahead and type Control + C and it breaks out of the command. Here on the screen, you can see the caret C that shows that indeed these commands were interrupted with Control + C. There's one more small piece of the puzzle left to cover before we use a while loop in our script to loop over all the positional parameters. This last piece of the puzzle is the shift to built-in. So the type -a shift, it's a shell built in, let's get some help on this here. It says it renames the positional parameters of N+1, N+2, to $1, $2 and so on. Now what the shift command really does, is that it removes positional parameters from the list, starting with the $1, it just chops off $1. So when you execute the shift command, the value stored in $1 is removed, it's just gone. What also happens is that the value stored in $2, shifts down to $1, $3 replaces the value in $2, 4 replaces the value in 3 and so on and so forth. Also the special parameter of $ pound sign is reduced by one. Now, as you remember $ pound sign contains the number of arguments that were supplied on the command line. By default, shift shifts everything one place. Executing shift by itself is the same thing as executing shift 1. If you wanna shift everything by two places, use shift 2. In that case $ pound sign will be decreased by two. If you wanna shift everything by three positions use shift 3 and so on. Now, if this sounds confusing, don't worry, it's actually harder to explain than it is to demonstrate. So when you see it being used in a script, it will make total sense. So let's do that right now. Let's use shift in our script. So we'll loop through all the positional parameters. We'll use a while loop while, double brackets here, again make sure there are spaces in between while and a double brackets, and a space after the double brackets. We're going to test for $ pound sign here, the number of parameters, and we'll say if it's greater than zero, that means if there were any arguments on the command line, then this will evaluate to true. And at that point, what we want to do, is echo the number of parameters is $ pound sign and then we'll echo the first parameter here. And we're just going to repeat this a couple of more times here. So will echo $2 and $3. Then we'll echo a blank line, and then what we're going to do, is use the shift the built in command. So just like we said, shift is actually going to modify $ pound sign because when it's executed it removes one parameter from the beginning, $1 is gone, it shifts everything down. So that means at that point the number of positional parameters has changed and $ pound sign has changed to reflect that. So we are modifying the condition that we are testing for through this loop. So we shouldn't end up in an infinite loop here. Of course, I'm going to end this with done, save my changes and then execute this script. So if we execute this script without any arguments, then there are no positional parameters to loop through. So that's why we only get the top portion of the script, displaying some output, but we don't get any of the commands in the while loop being executed. Now let's apply just one argument here that caused the while loop to execute one time. So $1 is assigned to apple, then shift occurs. And so that removes $1, it shifts everything down, well, there's nothing left to shift down. So $ pound sign evaluates to zero, so zero greater than zero is false. So the while loop stops executing because it's false. So let's go ahead and add another argument on the command line and see what happens. So we'll add bread. So the first time the loop gets executed $1 contains of apple $2 contains a bread. The shifts command is executed, apple goes away. The original $1 goes away, it gets lopped off the beginning of the list there. Bread which is stored in $2 then becomes $1 and there are no positional parameters, 2 and 3. So let's keep doing this and you can clearly see what's gonna happen. We'll do candy. At the outset of the script, $1 is apple, $2 is bread, $3 is candy. The first time the while loop is executed and shift gets executed, the number of parameters gets decreased by one. So then there are only two parameters bread and candy, bread being $1, candy being 2, while loop gets executed again, bread gets chopped off at the beginning there and you're only left with candy which then becomes $1. The shift command is executed again. Candy goes away and there are no more positional parameters. So zero greater than zero is false in the while loop exits. So let's do this again with one more argument. So as you can clearly see, every time we go through the while loop and the shift command is executed, everything shifts down by one. So the while loop executes four times and then exits. It might not be obvious when you would want to use the shift command beyond our while loop that we've demonstrated here. So here are a couple of thoughts to keep in mind. One time shift comes in handy, is when you want to have a user supply information as arguments to your script, and there is one argument or a piece of data that can contain multiple words. For instance, data you would want to use in the comment field when creating a user. In this case, you would tell the user to supply a username which would be $1, then you would shift, and then what is left over becomes the comments field $1, 2 and 3 and so on. Now that's one example. Also think about processing command line arguments for example, something like this -a --verbose. So just keep these ideas in mind and we'll be coming back to them in future lessons and exercises. To quickly recap, in this lesson you used positional parameters, starting with $1 explicitly, you reviewed the special variable of $ pound sign. You are also introduced to the true, sleep and shift commands. Finally you put all this new information together in order to create a while loop.

About the Author
Learning Paths

Jason is the founder of the Linux Training Academy as well as the author of "Linux for Beginners" and "Command Line Kung Fu." He has over 20 years of professional Linux experience, having worked for industry leaders such as Hewlett-Packard, Xerox, UPS, FireEye, and Nothing gives him more satisfaction than knowing he has helped thousands of IT professionals level up their careers through his many books and courses.

Covered Topics