Chapter 6. Iterating with Loops

Remember, scripts are for lazy people. We are the folk of the world who have better things to do than repeat a task 100 times or more; loops are our friends.

Looping structures are the life-blood of scripts. These loops are the workhorse engine that can iterate many times, repeating the same task reliably and consistently. Imagine having 100,000 lines of text within a CSV file that has to be checked for incorrect entries. A script can do this easily and accurately once developed but in the case of a human, the reliability factor and accuracy will fail very quickly.

So let's see how we can save our time and sanity by covering the following topics in this chapter:

  • For loops
  • Loop control
  • While and until
  • Read from file
  • Operator menu

For loops

All our looping controls can be simple and we will begin by looking at for loops. The word for is a keyword in bash and in working it is similar to if. We can use the command type to verify this, as shown in the following example:

$ type for
for is a shell keyword

As a reserved shell keyword, we can use a for loop both in scripts and directly at the command line. In this way, we can utilize loops within and without the scripts optimizing the use of the command line. A simple for loop is shown in the following example code:

# for u in bob joe ; do
useradd $u
echo '$u:Password1' | chpasswd
passwd -e $u
done

Within a for loop, we read from the list on the right to populate the variable parameter on the left, in this case we will read from the list containing bob and joe into the parameter variable u. Each item from the list is inserted into the variable, one item at a time. In this way, as long as there are items to be processed in the list, the loop will execute until the list is exhausted.

Practically, for us the execution of this loop means that we will:

  • Create the user bob
  • Set the password for bob
  • Expire the password so it will need to be reset on the first login for the user bob

We then loop back and repeat the process for the user joe.

We can view the previous example in the following screenshot; after having gained root access via sudo -i, we proceeded to run the loop and create the users:

For loops

The list that is read in the for loop can be generated dynamically or statically, as shown in the last example. To create dynamic lists, we could use various globbing techniques to populate the list. As an example, to work with all files in a directory we could use *, as shown in the following example:

for f in * ; do
stat "$f"
done

Note

When a list is generated, such as with file globbing, we should quote the expansion of the variable parameter. Without the quotes, it is possible that a space will get included that will cause the command to fail. This is what we have seen here in the stat command.

In the following examples, we isolate the filenames that begin with ba*. We then use the stat command to print the inode metadata. The code and output is shown in the following screenshot:

For loops

This list can also be generated from the output of another command or a pipeline of commands. For example, if we need to print the current working directory of all logged in users, we could try something similar to the following:

$ for user in $(who | cut -f1 -d"") ; do
lsof -u $user -a -c bash | grep cwd
done

In the previous example, we can see that the choice of name for the parameter is down to you; we are not limited to a single character and we can use the $username in this example. Using lowercase we will not overwrite the system variable $USER. The following screenshot demonstrates the loop and the subsequent output:

For loops

The lsof command will list open files, we can search for the files opened by each user in turn and with the bash command as the current working directory.

Working with the scripts that we have created so far, we can create a new script called hello9.sh. If we copy the $HOME/bin/hello2.sh script to the new script, we can edit it to make use of a for loop:

#!/bin/bash
echo "You are using $(basename $0)"
for n in $*
do
    echo "Hello $n"
done
exit 0

The loop is used to iterate through each command-line argument supplied and greet each user individually. When we execute the script, we can see that we can now display the hello message for each user. This is shown in the following screenshot:

For loops

Although, what we have seen here is still relatively trivial, we should now realize a little of what we can do with scripts and loops. The arguments of this script can be the usernames that we have already used or anything else. If we stick with the usernames, then it will be very easy to create user accounts and set passwords, as we saw earlier.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.72.176