bash scripting
Linux

Bash scripting the awesome guide Part2

In the previous post, we talked about how to write a bash script. And we’ve seen how bash scripting is awesome. In this post, we continue to look at structured commands that control the flow of your shell scripts. You’ll see how you can perform repeating processes; this post demonstrates for loop, while in bash scripts

we will discuss the following:

for command

Iterating over simple values

Iterating over complex values

Reading values from a command

The field separator

Iterating over directory files

for Command C-Style

The while Command

Nesting Loops

Looping on File Data

Controlling the Loop

The break command

The continue command

Processing the Output of a Loop

Useful Examples

for Command

The bash shell provides the for command to allow you to create a loop that iterates through a series of values. This is the basic format of the bash shell for command

for var in list

do

commands

done

In each iteration, the variable var contains the current value in the list. The first iteration uses the first item in the list; the second iteration contains the second item, and so on until the end of the list items

Iterating over simple values

The most basic use of the for command in bash scripting is to iterate through a list of simple values like this

As you can see from the output the $var variable is changed on every loop cycle till the last item on the list.

bash scripting for loop

Notice that the $var variable retained its value and allowed us to change the value and use it outside of the for command loop, like any variable.

Iterating over complex values

Your list maybe contains some comma or two words but you want to deal with them as one item on the list.

This example we have some of those

We play nice till now, always we do. Just keep reading and practicing.

bash scripting compelx for loop

Reading values from a command

Another way to a list is to use the output of a command. You use command substitution to execute any command that produces output.

This example uses the cat command in the command substitution to display the contents of the file states. Notice that our file contains one word per line, not separated by spaces.

bash scripting loop from command

Notice that our file contains one word per line, not separated by spaces.

The for command still iterates through the output of the cat command one line at a time, assuming that each line has one word. However, this doesn’t solve the problem of having spaces in data.

If you list that contains words with spaces in it, the for command still takes each word as a separate value. There’s a reason for this, which we look at now.

The field separator

The cause of this problem is the special environment variable IFS, called the internal field separator. By default, the bash shell considers the following characters as field

  • Space
  • Tab
  • newline

If the bash shell sees any of these characters in the data, it assumes that you’re starting a new data field in the list.

To solve this problem, you can temporarily change the IFS environment variable values in your bash script suppose that you want to separate by new lines so it will be like this

IFS=$'\n'

So after you add this to your bash script it will ignore spaces and tabs and consider new lines as a separator.

You got it. Bash scripting is easy just little attention

bash scripting passwd file

In this case, the separator is colon like the case of /etc/passwd file which contains the user’s information you can assign it like this

IFS=:

How bash scripting is awesome?

Iterating over directory files

One of the most common things when using for loop in bash scripting is iterate over files in a directory and deal with them.

For example, we want to list the file inside /home directory so the code will be like this

From the previous post, you should know the if statement and how to differentiate between files and folders, so if you don’t know I recommend you to review it bash script step by step.

bash scripting directory iteration

Here we use wildcard character which is asterisk * and this is called in bash scripting file globbing which is a process of producing filenames automatically that matches the wildcard character in our case asterisk means All files with all names

Notice that in the if statements here we quote our variables with quotations because maybe the file or the folder name contains spaces

Sure enough, it lists all files and directories in that folder

for Command C-Style

If you know c language you may found that the for loop here is weird because you are familiar with this syntax

for (i = 0; i < 10; i++)

{

printf(“number is %d\n”, i);

}

The bash scripting also supports a version of the for loop that looks similar to the C-style for loop with little difference here’s the syntax.

for (( variable assignment ; condition ; iteration process ))

So it looks like this

for (( a = 1; a < 10; a++ ))

And if you want to write in that style go ahead and do that

And this is the output

bash scripting c-style

The while Command

The for loop is not the only way of looping in bash scripting. The while command allows you to define a command to test and then loop through a set of commands as long as the defined test command returns a zero exit status which means success. It tests the test command at the start of each iteration. When the test command returns a nonzero exit status means fail, the while command stops executing the commands

And this is the format of while loop command

while test command

do

other commands

done

and here is an example

The script is simple; it starts with while command to check if var1 is greater than zero then the loop will run and the var1 value will be decreased every time by 1 and on ever loop iteration it will print the value of var1, Once the var1 value is zero the loop will exit.

bash scripting while loop

If we don’t decrease the value of var1 it will be the same value and the loop will be infinite.

Nesting Loops

A loop statement can use any other type of command within the loop, including other loop commands. This is called a nested loop.

Here’s an example of nested loops.

As you can see from the results the outer loop hits first then goes into the inner loop and completes it and go back to the outer loop and so on.

bash scripting nested loops

Looping on File Data

This is the most common usage for the for loop in bash scripting.

We can iterate over file content for example /etc/passwd file and see what we will get

Here we have two loops, the first loop iterate over the lines of the file and the separator is the newline, the second iteration is over the words on the line itself and the separator is the colon :

bash scirpting file data

You can apply this idea when you have CSV or any comma separated values file or whatever. The idea is the same; you just will change the separator to fit your needs.

Controlling the Loop

Maybe after the loop starts you want to stop at a specific value, will you wait until the loop is finished? Of course not, there are two commands help us in this.

  • break command
  • continue command

The break command

The break command is a simple way to escape a loop. You can use the break command to exit any type of loop, including while and until loops.

The for loop should normally have iterated through all the values in the list.

bash scirpting break command

However, the shell executed the break command, which stopped the for loop

And the same for the while loop

The while loop terminated when the if-then condition was met, executing the break command.

bash scipting break while

The continue command

The continue command is a way to prematurely stop processing commands inside of a loop but not terminate the loop completely.

Here’s a simple example of using the continue command in a for loop

When the conditions of the if-then statement are met (the value is greater than 5 and less than 10), the shell executes the continue command, which skips the rest of the commands in the loop, but keeps the loop going.

bash scripting continue command

Processing the Output of a Loop

You can either pipe or redirect the output of a loop within your shell script. You do this by adding the processing command to the end of the done command.

So instead of displaying the results on screen, the shell redirects the results of the for command to the file or whatever

The shell creates the file myfile.txt and redirects the output of the for command to the file. And if we check that file we will find our loop output inside it.

bash sciprintg process output

Let’s employ out bash scripting knowledge in something useful.

Useful Examples

Finding executables

If you want to find what executable files are available on your system for you to use, just scan all the folders in the PATH environment variable. We discussed for loop and if statements and file separator so our toolset is ready. Let’s combine them together and make something pretty

This is just awesome. We were able to get all the executables on the system that we can run them.

bash scripting finding executables

Now nothing stops you except your imagination. And this is the beauty of bash scripting

This for now, I hope you enjoy the article and learn a new thing or at least review your knowledge if you forget it. My last word is keep reading and practicing.

Thanks

  • Pingback: Why Linux bash scripting is awesome | Ace Infoway()

  • Pingback: cron.weekly issue #67: Kubernetes, Brotli, Beehive, Takeover, MySQL 8, Nomad, tmux, fail2ban & more()

  • Pingback: Linux bash scripting the awesome guide part3 - Like Geeks()

  • clfapujc

    In the last example there is:

    for folder in $PATH
    How does the script know that we are looking for actual folders. We never used -d to specify we wanted directories.

    • When we use the asterisk * it means all files and directories in that folder.
      so we get files and directories BOTH of them without filtering .
      the filtration to get the folders is on the second if statement which is.

      for file in $folder/*

      then we search for the executable with -x

      • clfapujc

        Now I get it. Thanks.
        For a nearly total noob it is confusing 😛

    • Amani Hamis

      If I understood your question: I think the $PATH global variable only contains a list of folders in which the executables are stored, separated by “:”. To see these folders on your system just type echo $PATH. On my system, it returns the string “/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin”
      None of those can be a file, so he didn’t need to filter.

      • Great comment really.
        Thanks for contribution.

        • Amani Hamis

          GREAT articles btw! I’m learning SO MUCH!
          I started at Linux file system->Main Linux Commands->Main Linux Commands (Part 2) -> Linux Environment Variables -> Linux Command Line Tricks -> Bash Script Step-by-Step ->Bash Scripting Part 2 -> Part 3 where I am currently 🙂
          Thanks, and don’t stop delivering!

          • Great to know that.
            I do my best to post quality content.
            Hope the community love it.
            Regards.

  • Pingback: 31+ Examples for sed Linux command in text manipulation - Like Geeks()