Book Image

Linux Shell Scripting Cookbook - Third Edition

By : Clif Flynt, Sarath Lakshman, Shantanu Tushar
Book Image

Linux Shell Scripting Cookbook - Third Edition

By: Clif Flynt, Sarath Lakshman, Shantanu Tushar

Overview of this book

The shell is the most powerful tool your computer provides. Despite having it at their fingertips, many users are unaware of how much the shell can accomplish. Using the shell, you can generate databases and web pages from sets of files, automate monotonous admin tasks such as system backups, monitor your system's health and activity, identify network bottlenecks and system resource hogs, and more. This book will show you how to do all this and much more. This book, now in its third edition, describes the exciting new features in the newest Linux distributions to help you accomplish more than you imagine. It shows how to use simple commands to automate complex tasks, automate web interactions, download videos, set up containers and cloud servers, and even get free SSL certificates. Starting with the basics of the shell, you will learn simple commands and how to apply them to real-world issues. From there, you'll learn text processing, web interactions, network and system monitoring, and system tuning. Software engineers will learn how to examine system applications, how to use modern software management tools such as git and fossil for their own work, and how to submit patches to open-source projects. Finally, you'll learn how to set up Linux Containers and Virtual machines and even run your own Cloud server with a free SSL Certificate from letsencrypt.org.
Table of Contents (14 chapters)

Field separators and iterators

The internal field separator (IFS) is an important concept in shell scripting. It is useful for manipulating text data.

An IFS is a delimiter for a special purpose. It is an environment variable that stores delimiting characters. It is the default delimiter string used by a running shell environment.

Consider the case where we need to iterate through words in a string or comma separated values (CSV). In the first case, we will use IFS=" " and in the second, IFS=",".

Getting ready

Consider the case of CSV data:

data="name,gender,rollno,location" 
To read each of the item in a variable, we can use IFS. 
oldIFS=$IFS 
IFS=, # IFS is now a , 
for item in $data; 
do 
    echo Item: $item 
done 

IFS=$oldIFS

This generates the following output:

Item: name
Item: gender
Item: rollno
Item: location

The default value of IFS is a white-space (newline, tab, or a space character).

When IFS is set as , the shell interprets the comma as a delimiter character, therefore, the $item variable takes substrings separated by a comma as its value during the iteration.

If IFS is not set as , then it will print the entire data as a single string.

How to do it...

Let's go through another example usage of IFS to parse the /etc/passwd file. In the /etc/passwd file, every line contains items delimited by :. Each line in the file corresponds to an attribute related to a user.

Consider the input: root:x:0:0:root:/root:/bin/bash. The last entry on each line specifies the default shell for the user.

Print users and their default shells using the IFS hack:

#!/bin/bash 
#Desc: Illustration of IFS 
line="root:x:0:0:root:/root:/bin/bash"  
oldIFS=$IFS; 
IFS=":" 
count=0 
for item in $line; 
do 

     [ $count -eq 0 ]  && user=$item; 
     [ $count -eq 6 ]  && shell=$item; 
    let count++ 
done; 
IFS=$oldIFS 
echo $user's shell is $shell;

The output will be as follows:

root's shell is /bin/bash

Loops are very useful in iterating through a sequence of values. Bash provides many types of loops.

  • List-oriented for loop:
        for var in list; 
        do 
            commands; # use $var 
        done 

A list can be a string or a sequence of values.

We can generate sequences with the echo command:

echo {1..50} ;# Generate a list of numbers from 1 to 50.
echo {a..z} {A..Z} ;# List of lower and upper case letters. 

We can combine these to concatenate data.
In the following code, in each iteration, the variable i will hold a character in the a to z range:

      for i in {a..z}; do actions; done;
  • Iterate through a range of numbers:
        for((i=0;i<10;i++)) 
        { 
           commands; # Use $i 
        }
  • Loop until a condition is met:

The while loop continues while a condition is true, the until loop runs until a condition is true:

        while condition 
        do 
            commands; 
        done

For an infinite loop, use true as the condition:

  • Use a until loop:

A special loop called until is available with Bash. This executes the loop until the given condition becomes true. Consider this example:

        x=0; 
        until [ $x -eq 9 ]; # [ $x -eq 9 ] is the condition 
        do 
            let x++; echo $x; 
        done