Table of Contents for
Learning Linux Shell Scripting

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Learning Linux Shell Scripting by Ganesh Sanjiv Naik Published by Packt Publishing, 2015
  1. Cover
  2. Table of Contents
  3. Learning Linux Shell Scripting
  4. Learning Linux Shell Scripting
  5. Credits
  6. About the Author
  7. Acknowledgments
  8. About the Reviewers
  9. www.PacktPub.com
  10. Preface
  11. What you need for this book
  12. Who this book is for
  13. Conventions
  14. Reader feedback
  15. Customer support
  16. 1. Getting Started and Working with Shell Scripting
  17. Tasks done by shell
  18. Working in shell
  19. Learning basic Linux commands
  20. Our first script – Hello World
  21. Compiler and interpreter – difference in process
  22. When not to use scripts
  23. Various directories
  24. Working more effectively with shell – basic commands
  25. Working with permissions
  26. Summary
  27. 2. Drilling Deep into Process Management, Job Control, and Automation
  28. Monitoring processes using ps
  29. Process management
  30. Process monitoring tools – top, iostat, and vmstat
  31. Understanding "at"
  32. Understanding "crontab"
  33. Summary
  34. 3. Using Text Processing and Filters in Your Scripts
  35. IO redirection
  36. Pattern matching with the vi editor
  37. Pattern searching using grep
  38. Summary
  39. 4. Working with Commands
  40. Command substitution
  41. Command separators
  42. Logical operators
  43. Pipes
  44. Summary
  45. 5. Exploring Expressions and Variables
  46. Working with environment variables
  47. Working with read-only variables
  48. Working with command line arguments (special variables, set and shift, getopt)
  49. Understanding getopts
  50. Understanding default parameters
  51. Working with arrays
  52. Summary
  53. 6. Neat Tricks with Shell Scripting
  54. The here document and the << operator
  55. The here string and the <<< operator
  56. File handling
  57. Debugging
  58. Summary
  59. 7. Performing Arithmetic Operations in Shell Scripts
  60. Using the let command for arithmetic
  61. Using the expr command for arithmetic
  62. Binary, octal, and hex arithmetic operations
  63. A floating-point arithmetic
  64. Summary
  65. 8. Automating Decision Making in Scripts
  66. Understanding the test command
  67. Conditional constructs – if else
  68. Switching case
  69. Implementing simple menus with select
  70. Looping with the for command
  71. Exiting from the current loop iteration with the continue command
  72. Exiting from a loop with a break
  73. Working with the do while loop
  74. Using until
  75. Piping the output of a loop to a Linux command
  76. Running loops in the background
  77. The IFS and loops
  78. Summary
  79. 9. Working with Functions
  80. Passing arguments or parameters to functions
  81. Sharing the data by many functions
  82. Declaring local variables in functions
  83. Returning information from functions
  84. Running functions in the background
  85. Creating a library of functions
  86. Summary
  87. 10. Using Advanced Functionality in Scripts
  88. Using the trap command
  89. Ignoring signals
  90. Using traps in function
  91. Running scripts or processes even if the user logs out
  92. Creating dialog boxes with the dialog utility
  93. Summary
  94. 11. System Startup and Customizing a Linux System
  95. User initialization scripts
  96. Summary
  97. 12. Pattern Matching and Regular Expressions with sed and awk
  98. sed – noninteractive stream editor
  99. Using awk
  100. Summary
  101. Index

Conditional constructs – if else

We use the if command to check the pattern or command status and accordingly we can make certain decisions to execute scripts or commands.

The syntax of the if conditional is as follows:

    if     command
    then
        command
        command
    fi

From the preceding syntax, we can clearly understand the working of the if conditional construct. Initially, if will execute the command. If the result of command execution is true or 0, then all the commands that are enclosed between then and fi will be executed. If the status of command execution after if is false or nonzero, then all the commands after then will be ignored and the control of execution will directly go to fi.

Let's learn another variation of if constructs.

Syntax:

    if command
    then
         command
        command
    else
        command
    fi

In the preceding case if the command after if is successfully executed or the status variable ? content is 0, then all the commands after then will be executed. If the result of the command is a failure or nonzero, then all the commands after else will be executed.

For numeric or string expression evaluations using if, the syntax is as follows:

    if [ string/numeric expression ]
    then
        command
    fi

Alternatively, use the following syntax:

    if [[ string expression ]]
    then
        command
    fi

Alternatively, use the following syntax:

    if (( numeric expression ))
    then
        command
    fi

The simple example to check the status of the last command executed using the if construct is as follows:

#!/bin/bash
if [ $? -eq 0 ]
then
        echo "Command was successful."
else
        echo "Command was successful."
fi

Whenever we run any command, the exit status of command will be stored in the ? variable. The preceding construct will be very useful in checking the status of the last command.

Numerical handling if constructs

Let's learn about using the if construct for numerical decision making.

We can use the test command for finding which variable contains the smaller value:

$ X=10
$ y=20
$ (( x < y ))
$ echo $?
0
The result 0 shows that x is smaller than y.

In the Shell script if_01.sh, we can use the test command along with the if construct for checking equality of variable with numerical value as follows:

#!/bin/bash
a=100
if [ $a -eq 100 ]
then
    echo "a is equal to $a"
else
        echo "a is not equal"
fi

Let's test the following program:

$ chmod +x if_01.sh
$ ./if_01.sh

The following will be the output after executing the preceding commands:

a is equal to 100

Use the script if_02.sh to check which product is costly. The script is as follows:

#!/bin/bash
echo "Enter the cost of product a"
read a
echo "Enter the cost of product b"
read b

if [ $a -gt $b ]
then
 echo " a is greater"
else
 echo " b is greater"
fi

Let's test the following program:

$ chmod +x if_02.sh
$ ./if_02.sh

The following will be the output after executing the preceding commands:

Enter the cost of product a
100
Enter the cost of product b
150
 b is greater
$

Using the command exit and the ? variable

If we need to terminate the Shell script and come back to command line, then we can use the exit command. The syntax is very simple:

exit 0

The given command will terminate the Shell script and return to the command line. It will store the 0 value in the status variable ?. We can use any value between 0 and 255. Value 0 means success and any other nonzero value means an error. We can use these values to indicate error information.

The script to check the value of a parameter, which is passed along with command, either less than 0 or greater than 30 is as follows. This will save our efforts of using the nested if statement:

#!/bin/bash
if (( $1 <  0 || $1 > 30 ))
    then
        echo "mdays is out of range"
        exit 2
fi

The test command used in the preceding expression for OR can be written as follows:

[ $1 -lt 0 -o $1 -gt 30 ]

String handling with the if construct

Let's learn about using string-related checking using the if command.

The following script if_03.sh will check the equality of two strings:

echo "Enter the first string to compare"
read name1
echo "Enter the Second string to compare"
read name2

if [ $name1 == $name2 ]
then
    echo "First string is equal to Second string"
else
    echo "Strings are not same"
fi

Let's test the following program:

$ chmod +x if_03.sh
$ ./if_03.sh

The following will be the output after executing the preceding commands:

$ ./ if_03.sh
Enter the first string to compare
LEVANA
Enter the Second string to compare
TECHNOLOGIES
Strings are not same
$ ./ if_03.sh

The following will be the output after executing the preceding commands:

Enter the first string to compare
LEVANA
Enter the Second string to compare
LEVANA
First string is equal to Second string
$

We will write the script for performing various other string operations using a test. Let's write the script if_04.sh to compare two strings for various attributes:

#!/bin/bash

str1="Ganesh"
str2="Naik"

if [ $str1 = $str2 ]
then
    echo "Two Strings Are Equal"
fi

if [ $str1 != $str2 ]
then
    echo "Two Strings are not equal"
fi

if [ $str1 ]
then
    echo "String One Has Size Greater Than Zero"
fi

if [ $str2 ]
then
    echo "String Two Has Size Greater Than Zero"
fi

Let's test the following program:

$ chmod +x if_04.sh
$ ./if_04.sh

The following will be the output after executing the preceding commands:

Two Strings are not equal
String One Has Size Greater Than Zero
String Two Has Size Greater Than Zero

If we want to verify whether the entered password is valid then script i_05.sh will be as follows:

#!/bin/bash
stty –echo        # password will not be printed on screen
read -p "Please enter a password  :" password
if test "$password" == "Abrakadabra"
then
echo "Password is matching"
fi
stty echo

Let's test the following program:

$ chmod +x if_05.sh
$ ./if_05.sh

The following will be the output after executing the preceding commands:

$ ./ if_05.sh
Please enter a password  :  levana
$ ./ if_05.sh
Please enter a password  : Abrakadabra
Password is matching
$

Checking for null values

Many a time we need to check the value of variable, such as is it null? The null value means zero value. If we want to create the string with the null value, then we should use double quotes "" while declaring it:

if [ "$string" = "" ]
then
echo "The string is null"
fi

We can even use [ ! "$string" ] or [ -z "$string" ] for null checking of strings.

Let's write the script if_08.sh, which will search if the entered person name is the user of the computer system:

#!/bin/bash
read -p "Enter a user name : " user_name

# try to locate username in in /etc/passwd
#
grep "^$user_name" /etc/passwd > /dev/null

status=$?

if test $status -eq 0
then
    echo "User '$user_name' is found in /etc/passwd."
else
    echo "User '$user_name' is not found in /etc/passwd."
fi

Let's test the following program:

$ chmod +x if_08.sh
$ ./if_08.sh

The following will be the output after executing the preceding commands:

Enter a user name : ganesh
User 'ganesh' is not found in /etc/passwd.

In the preceding script, we are searching the username in the /etc/passwd file. If a person's name is not found in the /etc/passwd file, then we can conclude that the username is not created in the system.

Let's write a script to check the disk space being used. The script will print a warning if 90 percent or more of the disk space is used on one of the mounted partitions.

The Shell script if_09.sh for solving the disk filesystem usage warning will be as follows:

#!/bin/bash
df -h | grep /dev/sda1 | cut -c 35-36 > log.txt
read usage < log.txt
if [ $usage -gt 80 ]
then
    echo "Warning – Disk file system has exceeded 80% !"
    echo "Please move extra data to backup device.
else
    echo "Good - You have enough disk space to continue working !"
fi

Let's test the following program:

$ chmod +x if_09.sh
$ ./if_0.sh

Due to some hardware differences, if the preceding program does not work, then make the following changes in the script:

  1. Check if your partition of storage is sda1, sda2, or any other by entering the $df –h command.
  2. Check if the % disk utilization value is at character count 35 and 36, if different then make changes in the code accordingly.

Using the df command, we get the disk filesystem usage information. The grep command is filtering the hard disk partition, which contains our data. Then, we filter the disc % utilization number and store that value in the log.txt file. Using the read command, we read the % utilization and store it in the variable usage. Later on using the if command, we check and warn the user if the % utilization is greater than 80.

File handling with the if command

You have already learned about how to use the test command for checking various file operations such as checking the file's permissions and similar other attributes. A command's task in any script is to check if the file or folder is present or not. Then accordingly, we need to proceed. We will see how to use the if command along with the test command.

Use the simple script if_10.sh to check if the file exists or not in the current directory as follows:

#!/bin/bash
read filename
if test -e $filename
then
    echo "file exists"
else
    echo " file does not exist"
fi

Let's test the program as follows:

$ chmod +x if_10.sh
$ ./if_10.sh

The following will be the output after executing the preceding commands:

sample.txt
file does not exist
$ touch sample.txt
$ ./ if_10.sh
sample.txt
file exists

First, we checked without the file. Then, we created a file with the touch command. We can very easily check the presence of the file.

Let's learn how to use the if command to check various file attributes, such as whether it exists, does it have file permissions to read, write, executable, and similar by writing script if_11.sh as follows:

#!/bin/bash
echo "$1 is: "
if ! [ -e $1 ]
then
  echo "..Do not exists"
  exit
else
  echo "file is present"
fi

if [ -x $1 ]
then
  echo "..Executable"
fi

if [ -r $1 ]
then
  echo "..Readable"
fi

if [ -w $1 ]
then
  echo "..Writable"
fi

Let's test the following program:

$ chmod +x if_11.sh
$ ./if_11.sh

Output:

sample.txt is:
"file is present"
..Readable
..Writable

The Shell script if_12.sh for performing the file copy operation, and then checking if the copy operation was successful or not, will be as follows:

#!/bin/bash
file1="File1"
file2="File2"
if cp $file1 $file2
then
  echo "Copy Command Executed Successfully"
  echo "Content of file named Fil1 copied in another file named File2"
else
  echo "Some problem in command execution"
fi

Let's test the program:

$ chmod +x if_12.sh
$ ./if_12.sh

The following will be the output after executing the preceding commands:

$ touch File1
$ ./ if_12.sh
Copy Command Executed Successfully
Content of file named Fil1 copied in another file named File2

Multiple test commands and if constructs

These type of constructs enable us to execute the second command depending on the success or failure of the first command:

command1    &&    command2
command1    ||    command2

Let's write script if_13.sh. In this script, we will ask the user to input two numbers. Then, the if statement will evaluate two expressions. If both are true, then the command after then will be executed, otherwise commands after else will be called:

#!/bin/bash
echo "Enter the first number"
read val_a
echo "Enter the Second number"
read val_b

if [ $val_a == 1 ] && [ $val_b == 10 ]
then
  echo "testing is successful"
else
  echo "testing is not successful"
fi

Let's test the program:

$ chmod +x if_13.sh
$ ./if_13.sh

The following will be the output after executing the preceding commands:

Enter the first number
10
Enter the Second number
20
testing is not successful

$ ./if_13.sh
Enter the first number
1
Enter the Second number
10
testing is successful

Sometimes, we may need to enter a command to check if the file has the execute permission? If it is executable, then the file should be executed. The script for such a requirement will be as follows:

test -e file &&  .  file.

Let's learn one more example of && and multiple expressions using the test command. In the next script if_14.sh, we will check if file_one is present, then we will print Hello and then immediately we will check if file_two is present, then we will print there on the screen:

#!/bin/bash

touch file_one
touch file_two

if [ -f "file_one" ] && echo "Hello" && [ -f file_two ] && echo  "there"
then
  echo  "in if"
else
  echo    "in else"
fi
exit 0

Let's test the program:

$ chmod +x if_14.sh.sh
$ ./if_14.sh

The following will be the output after executing the preceding commands:

Hello
there
in if

The following script if_15.sh will check file permissions such as read, write, and execute in the same if command using multiple && with the test command:

#!/bin/bash
echo "Please enter file name for checking file permissions"
read file
if [[ -r $file && -w $file && -x $file ]]
then
     echo "The file has read, write, and execute permission"
fi

Let's test the program:

$ chmod +x if_15.sh
$ touch sample.txt
$ chmod +rwx sample.txt
$ ./if_15.sh

The following will be the output after executing the preceding commands:

The file has read, write, and execute permissions.

Till now, we have seen multiple expressions using the && logical operator. Now we will see one example with the OR (||) logical operator. In the following script if_16.sh, we will check the existence of file_one and then we will print Hello on the screen. If the first expression of file checking fails, then the second expression of echo will be executed:

#!/bin/sh
if [ -f file_one ] || echo "Hello"
then
    echo "In if"
else
    echo "In else"
fi

Let's test the program:

$ chmod +x if_16.sh
$ ./if_16.sh

The following will be the output after executing the preceding commands:

hello
In if
$ touch file_one
$ ./if_16.sh

Output:

In if

We checked in the preceding script if file_one is absent or present.

The if/elif/else command

Whenever we need to take decision from multiple situations or options such as whether it a city is the capital of a country, the state capital, a major city, or a small town. In such situations where, depending on various options, we need to execute different commands, if/else or if/elif/else decision-making commands are useful.

Using the if/elif/else commands, we can have multiple decision-making processes. If the if command succeeds, the command after then will be executed. If it fails, the command after the elif statement will be tested. If that statement succeeds, then statements under the elif are executed. However, suppose none of the elif conditions are true, then statements after the else command are executed. Here, the else block is executed by default. The fi statement will close the if/elif/else command.

The syntax of decision making using the if elif construct is as follows:

If    expression_1
then
    Command

elif
     expression_2
then
    Command

elif
    expression_3
then
    Command

else
  Command

fi

Let's write script if_18.sh as follows. In this script, we are checking if the directory with a given name exists or not. If this fails, then we are checking whether the file with the given name exists. Even if this fails, then we will inform the user that neither the file nor the directory exists with the given name:

#!/bin/bash
echo "Kindly enter name of directory : "
read file

if [[ -d $file ]]
then
        echo "$file is a directory"
elif [[ -f $file ]]
    then
    echo "$file is a file."
 else
       echo "$file is neither a file nor a directory. "
fi

Let's test the program:

$ chmod +x if_18.sh
$ ./is_18.sh

The following will be the output after executing the preceding commands:

$ ./ if_18.sh
Kindly enter name of directory :
File1
File1 is a file.

$ mkdir dir1

$ ./ if_18.sh
Kindly enter name of directory :
dir1
dir1 is a directory

$ ./ if_18.sh
Kindly enter name of directory :
File007
File007 is neither a file nor a directory.

The null command

In many situations, we may need a command that does nothing and returns a success status such as 0. In such cases, we can use the null command. It is represented by a colon (:). For example, in the if loop, we do not want to put any command if it is successful, but we have certain commands to execute if it fails. In such situations, we can use the null command. This is illustrated in the following if_19.sh script. If we want to loop forever, then the null command can be used in the for loop:

#!/bin/bash
city=London
if grep "$city" city_database_file >& /dev/null
then
      :
else
      echo "City is not found in city_database_file "
      exit 1
fi

Let's test the program:

$ chmod +x if_19.sh
$ ./if_19.sh

The following will be the output after executing the preceding commands:

City is not found in city_database_file

We can observe from the preceding script that the colon is a null command and it does nothing.