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:
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:
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:
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
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:
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 $user
name in this example. Using lowercase we will not overwrite the system variable $USER
. The following screenshot demonstrates the loop and the subsequent output:
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:
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.
3.129.72.176