14 Bash Shell Scripting – 2

Mr. Hardik Joshi

epgp books
  1. Performing Calculations in Shell Scripting

 

In the previous module, we have seen how to define a variable, assign values to the variable and retrieve the stored values. The values assigned to variables were treated as strings. When we want to perform numerical operations on these values, it cannot be done in a straight forward way like c=a+b because these variables contain strings. Let us see what happens if we perform simple addition operation on string.

 

a=10

b=15

c=$a+$b

echo “Total is: $c”

Output:

Total is:10+15

 

In the following sections, we will explore how to perform arithmetic operations on shell variables. There are four different ways used to perform calculations in shell scripting. These commands convert strings into numbers and perform the desired arithmetic operation. A programmer is free to use any of the following commands to perform arithmetic operations:

  • expr (compiled application for integer arithmetic operations)
  • Using $((…))
  • let (built-in shell command)
  • bc (compiled application for floating point operations)

We can use the above techniques on command prompt as follows:

 

$expr 2 + 5

$echo $((2+5))

$let x=( 2 + 5 )

$echo $x

$echo “2 + 5” | bc

 

Commands like expr and bc are widely used by shell programmers. Techniques like $((…)) and let command are not used frequently, the main reason is probably they are not supported by other shells. Let us explore expr, let and bc commands in detail with sample shell scripts.

 

expr : Evaluation Expressions

 

expr command evaluates arithmetic expressions and helps to perform integer calculations. The syntax of expr is:

 

expr arg1 operator arg2

 

Few Examples:

$expr 2 + 3

$a=5

$b=10

$expr $a + $b

$expr $a \* $b

 

It must be noted that the operator used for multiplication, asterisk (*) is treated as a wildcard character by shell, that is why we have to use escape sequence (\) while performing multiplications.

 

The following shell script performs basic arithmetic calculations using expr command over two variables. Here we have used command substitution so that the expression gets evaluated first and the results are stored in the variable “ans”.

 

 

Note: expr command can also be used to find the substring of a given string or length of a given string. We request you to read the manual of expr for more details. (use man expr)

 

let : Assigning and Evaluating expressions

 

The let command performs integer calculations as we did with expr command. However, when we use let command, there is no need to use the ‘$’ sign with variables and use command substitution as with expr. let command evaluates the expression and stores the values in the variable. The syntax of let command is:

let variable=value/expression [variable2=value/expression…]

 

 

bc : Base Conversion

 

The bc calculator can be used within shell scripts to perform floating point operations. However, while using in shell scripts, we have to pass the expression to bc using pipe (|) symbol. As we know that bc can be invoked from command prompt and allows us to perform calculations. We can also specify the variable scale to get precise answers while working with floating point numbers. The following script demonstrates the use of bc:

 

  1. Decision Making

Decision making is a key part of any programming language. Every language provides if-else statement for decision making within the programs. However, for each language the syntax and keywords may vary. Bash shell programming provides two different constructs for decision making. The programmer has a choice to use either of the followings:

  • if-then-else-fi statement
  • case-esac statement

The conditional statements in shell programming have far more capabilities when compared to those of programming languages like C, C++ etc. The main reason being, it allows us to use wildcard characters within the statement. Let us explore the syntax of each one of the above.

 

If Statement

 

The if-then-else statements are considered as control statements. Depending on the condition, selected statements are executed and hence it decides the flow of script. The if-then-else construct takes three different forms. Let us first see the syntax and later explore the scripts using these forms.

 

# First form if condition then commands

fi

# Second form if condition thencommands

else commands

fi

# Third form if condition then

commands elif condition then commands

fi

 

In the first form, if the condition is true, then commands are executed. If the condition is false, nothing is done and the control comes out of the if statement.

 

In the second form, if the condition is true, then the first set of commands is executed and if the condition is false, then second set of commands is executed.

 

In the third form, if the condition is true, then the first set of commands is executed, if the condition is false, and if the second condition is true, then the second set of commands is executed. In the third form, the if construct checks for two conditions.

 

It must be noted that each if block ends with a fi. Let us see a simple script that demonstrates the working of if-else statement

 

 

The above script will try to display the contents of /etc/passwd file. If the cat command executes successfully (that is, exit status of cat is 0) then the “File /etc/passwd displayed” message will be seen on terminal. In case if the cat command does not execute properly due to insufficient permissions or some other reason (exit status is 1)then the “Some error occurred…” message will be seen on terminal.

 

test and [] command: companion of if

 

The test command is used often with if statements to perform true/false decisions. The test command can be used to compare numbers, check files and directories or check strings. The test command checks the expression and exists with status either 0 (expression is rue) or 1 (expression is false). The test command can be used with the keyword test or using the notation []. It takes two forms as shown below:

 

The test command can be used for three main purposes in conjunction with if statement. Test can be used to:

  •  Compare two numbers
  • Compare two strings or a single string for null value
  • Check the attributes of a file/directory

test command can also be used with loop constructs within shell scripts, however, we will explore its usage with if statements. As such, test command does not display any output but simply returns a status of $?. We must take care that there has to be blank space between expression and square brackets (‘[‘ and ‘]’). Let us explore how test can be used with the above conditions.

 

Numeric Comparison

 

The test command can be used to compare two numbers. The comparison operators always begin with a ‘–‘ (hyphen) as shown in below table:

 

 

The above script displays the larger number from the two numbers input by the user. We can use the following form:

if test $a -gt $b instead of if [ $a -gt $b ]

 

String Comparisons

 

Test command can be used to compare two strings for equality, it can also be used to check whether a string is null or not. The following table summarizes the operators used for string comparison.

 

Output:

 

Both the strings are different.

 

File Checks

 

The test command can be used to test various file attributes. It also tests whether a string is a file or a directory. The following table summarizes few parameters to check file attributes

 

 

Case – Esac

 

The following is a code which helps use to check whether the user has entered yes or no. However, there are few issues in the following program. The user may enter y for yes or YES in capitals. Under such circumstances, the following program may not give expected output.

 

 

The above program has few logical bugs. What if the user enters Yes or YES or yes or Y or y. If we try to incorporate each test condition, the if-else statements will become too complicated. Such kind of issues can be well addressed by using case-esac construct rather than if-else statements. The following code looks much cleaner:

 

 

The case-esac statements are generally used when there are multiple conditions to be checked. It also supports wildcard characters to match appropriate patterns. The syntax is:

case $variable-name in

patterns ) commands ;;

patterns ) commands ;;

…..

esac

The following script demonstrates pattern matching with case-esac construct. Using regular expressions within case statements, we can check whether the word entered by a user starts with a vowel or a consonant.

 

 

Let us see one more script where we check whether the single character entered by the user is a letter or a digit. Patterns like [:lower:] and [:upper] will classify the typed character as a lower case or upper case

 

  1. Loop Constructs

Loops are important part of any programming language. They are used to perform iterative operations. Usually, a loop has a condition to identify the terminating criteria. A loop may iterate for ‘n’ number of times depending on some condition. In bash shell scripting, we can use three types of loops. The following loop constructs are explored in this section:

  • While loop
  • Until loop
  • For loop

    While Loop

 

The while command causes a block of code to be executed over and over, as long as the exit status of a specified expression is true.

Syntax of while loop

while condition is true

do

Statement(s) to be executed if condition is true done

Here is a simple example of a program that displays from zero to ten:

 

 

In the above program, we have initialized the number with zero. The loop tests for condition whether number is less that or equal to (le) 10 in each iteration. We have also used the statement number=$((number + 1)) to increment the number variable in each iteration.

 

Until Loop

 

The until loop is reverse of while loop. The until command causes a block of code to be executed over and over, as long as the exit status of a specified expression is false.

 

Syntax of until loop is:

until condition is false

do

Statement(s) to be executed if condition is false done

Following is a sample script that uses until loop.

 

 

In the above script, notice that we have reversed the condition. The condition is reversed by using ‘!’ sign. We can use either while or until loop. Both the loops behave in similar manner except the interpretation of condition.

 

For Loop

 

The for loop of shell programming is different from conventional for loops used in C/C++ or Java programming languages. In shell scripting, for loop iterates for the list of values specified. We provide a list of values within for loop construct, the looping variable picks up each value and iterates for ‘n’ number of values provided in the construct. Syntax of for loop is:

 

for variable_name in list

do

commands

done

 

The following script demonstrates the use of for loop. In this script the loop will iterate 3 times, in each iteration it will select word1, word2 and word3 respectively.

 

In the above script, the ls command is executed first to generate a list of files and directories. This list is used by the for loop to display line count for each file. We have also used file condition check to avoid the line count of directories, which may generate errors.

 

Let us modify the above script where we accept file names as command line 13 arguments (script parameters). The following script has to be executed by specifying command line arguments at $ prompt.

 

In the above script, we have used $* and $@ to list all the parameters passed at command line. As we have discussed in previous module, $* will treat all the arguments as a single string whereas “$@” will treat each argument as separate string. Here, we have to generate a list of file names in for loop which is to be processed separately, it is advisable to use “$@” instead of $*.

 

Let us discuss another script that combines loop and case statement together. The following script will iterate until user enters ‘0’ to exit the script. It uses until loop to repetitively ask for a choice and uses case to perform the operation according to the choice entered by the user.

 

 

We can enhance the functionality of shell scripts when we combine features of bash like command substitution, meta-characters, script parameters with loops and if statements. Looping constructs and if statements can be used to perform file processing. In the next module we will explore few features of file processing along with loops.

 

Summary:

  • Numerical calculations can be performed using expr, let or bc command.
  • The test command provides conditions to compare numbers, check strings and check file attributes.
  • The while loop and until loop iterate depending on some condition. while and until loop have similar syntax, however they are reverse of each other while checking for condition.
  • The for loop iterates for a given list of words. The number of iterations depends on the count of words that are listed.
  • We can enhance the functionality of shell scripts when we combine features of bash like command substitution, script parameters with loops and if statements.

Keywords:

 

conditional statements, loop construct, test expression, commands:expr, let, bc

you can view video on Bash Shell Scripting – 2

References:

 

[1] Jain, 100 Shell Programs in Unix. Pinnacle Technology, 2009.

[2] Garrels, Bash Guide for Beginners (Second Edition). Fultus Corporation, 2010.

[3] Isrd, Basics Of Os Unix And Shell Programming. Tata McGraw-Hill Education, 2006.

[4] Seebach, Beginning Portable Shell Scripting: From Novice to Professional. Apress, 2008.

[5] Foster-Johnson, J. C.Welch, and M. Anderson, Beginning Shell Scripting. John Wiley & Sons, 2007.

[6] Robbins and N. H. F. Beebe, Classic Shell Scripting: Hidden Commands that Unlock the Power of Unix. O’Reilly Media, Inc., 2005.

[7] Peters, Expert Shell Scripting. Apress, 2009.

[8] G. Venkateshmurthy, Introduction to Unix and Shell Programming. Pearson Education India, 2005.

[9] Festari, Learning Shell Scripting with Zsh. Packt Publishing Ltd, 2014.

[10] Newham, Learning the bash Shell: Unix Shell Programming. O’Reilly Media, Inc.,2005.

[11] Rosenblatt and A. Robbins, Learning the Korn Shell. O’Reilly Media, Inc., 2002.

[12] E. S. Jr, Linux Command Line. NO STARCH Press, 2012.

[13] Blum and C. Bresnahan, Linux Command Line and Shell Scripting Bible. John Wiley & Sons, 2015.

[14] Blum and C. Bresnahan, Linux Command Line and Shell Scripting Bible. John Wiley & Sons, 2015.

[15] Lakshman, Linux Shell Scripting Cookbook. Packt Publishing Ltd, 2011.

[16] Tushar, Linux Shell Scripting Cookbook. Packt Publishing Ltd, 2013.

[17] O. Burtch, Linux Shell Scripting with Bash. Sams, 2004.

[18] K. Michael, Mastering Unix Shell Scripting: Bash, Bourne, and Korn Shell Scripting for Programmers, System Administrators, and UNIX Gurus. John Wiley & Sons, 2011.

[19] Johnson, Pro Bash Programming: Scripting the Linux Shell. Apress, 2009.

[20] Veeraraghavan, Sams Teach Yourself Shell Programming in 24 Hours. Sams Publishing, 2002.

[21] Parker, Shell Scripting: Expert Recipes for Linux, Bash and more. John Wiley & Sons, 2011.

[22] F. A. Johnson, Shell Scripting Recipes: A Problem Solution Approach. Dreamtech Press, 2007.

[23] Verma, Unix and Shell Programming. Laxmi Publications, 2006.

[24] A. Forouzan and R. F. Gilberg, UNIX and Shell Programming: A Textbook. Brooks/Cole-Thomson Learning, 2003.

[25] P. Kanetkar, Unix Shell Programming. BPB Publications, 2002.

[26] Sanchez-Clark, Unix Shell Scripting Interview Questions, Answers, and Explanations: Unix Shell Certification Review. Equity Press, 2007.

[27] Taylor, Wicked Cool Shell Scripts: 101 Scripts for Linux, Mac OS X, and Unix Systems. No Starch Press, 2004.