Shell Scripting

You don’t have access to this lesson
Please register or sign in to access the course content.

Shell scripting is a program with a series of commands to execute using the shell. It is open-source.

A shell of OS takes input from users in the form of commands and processes it to result an output.

In this section, we’ll talk about some of the basics of shell scripting so that you can write your own scripts for Linux/Unix systems.

Prerequisites

  • Basic knowledge of interactive Unix/Linux shell (knowledge of OS)
  • Minimal programming knowledge like the use of variables, functions, etc.
  • Knowledge of some basic commands (ls, cp, echo, cd, etc.)

How to write the first shell script in Unix/Linux

Shell scripts can be written using text editors on your Linux system. Now, open a new file in your favorite text editor, give permission to execute, and start writing the scripts. We’ll be using vim as an editor for this tutorial.

Steps:

  • Create a file using vi editor and name the script file first_script.sh (or name it as you wish)
  • Write the following code in first_script.sh:
#!/bin/sh
# This is a comment!
echo Hello World        # This is also a comment!

Here, in the first line, #! is a unique operator called she-bang which directs all the commands followed to the Bourne Shell. This means our scripts will be interpreted by Bourne shell.

# is a special symbol to use or mark a line as a comment.

echo Hello World is a shell command to output Hello World!

  • Give the script file the permission to exehttps://us04web.zoom.us/j/9236298649?pwd=lvUXRJxvR3P2s2uYGFSyt5QDE8GHo5.1cute and run:
$ chmod 755 first_script.sh
$ ./first_script.sh

Output:

Hello World

Which is the same as running echo Hello World!.

Now let’s make a few changes to our script file:

#!/bin/sh
# This is a comment
echo "Hello       World"       # This is also a comment!

Here, we’ve added spaces between two parameters. But it doesn’t care about the spaces or TAB between them. It results the same as above with only one space.

DIY:

Create a file called second_script.sh and type in the following script and try to guess the outcome.

#!/bin/sh
# This is a comment!
echo "Hello       World"       # This is also a comment!
echo "Hello * World"
echo Hello * World
echo `Hello` World
echo Hello "     " World
echo Hello      World
echo "Hello  \"World\""

Note: \ ‘backslash’ is an escape character. Which is used as a special character so that the character next to it is kept as it is. So the result of the command echo "Hello \"World\"" will be Hello "World".

Variables

A symbolic name that is used to store, read and manipulate information.

Example:

#!/bin/sh
GREETING="Hello World"
echo $GREETING

Here, the string Hello World is assigned to variable GREETING then echo is used to out the value of the variable.

or you can also use multiple variables as:

#!/bin/sh
GREETING1=Hello 
GREETING2=World
echo $GREETING1 $GREETING2

To set variable name interactively:

#!/bin/sh
echo Hey, what u doing?
read DOING
echo "Hello, I'm $DOING."

Here, the command read is used so that you can take the value of variable DOING from the input.

Basic Operators

Various operators supported on the shell are:

  • Arithmetic
  • Boolean
  • String
  • Relational
  • File Test

Arithmetic Operators

OperatorDescriptionExpression
+ (Addition)Adds values`expr $var1 + $var2`
– (Subtraction)Subtracts from left hand operand`expr $var1 – $var2`
* (Multiplication)Multiplies values`expr $var1 \* $var2`
/ (Division)Divides left by right`expr $var1 / $var2`
% (Modulus)Divides left by right and returns remainder`expr $var1 % $var2`
= (Assignment)Assigns right operand to left operand$var1 = $var2
!= (Not Equality)Compares and returns true if different[ $var1 != $var2 ] 
== (Equality)Compares and returns true if both are same[ $var1 == $var2 ] 

Note: All conditional expressions should be inside square brackets and must be space around them. And, [ $var1 != $var2 ]  is correct whereas, [$var1 != $var2] is incorrect.

Boolean(Logical) Operators

OperatorDescriptionExpression
!Inverts the condition[ ! false ]
-oLogical OR. If one is true then the whole condition becomes true[ $var1 -lt 20 -o $var2 -gt 100 ]
-aLogical AND. If both are true then the whole condition becomes true[ $var1 -lt 20 -a $var2 -gt 100 ]

String Operators

OperatorDescriptionExpression
=The condition becomes true if two operands are equal[ $str1 = $str2 ] 
!=The condition becomes true if two operands are not equal[ $str1 != $str2 ] 
-zChecks whether string operand size is zero or not. If zero, it returns true[ -z $str1 ]
-nChecks if string operand size is non-zero. If non-zero, it returns true[ -n $str1 ]
strChecks if str is not an empty string. If empty, it returns false[ $str1 ] is not false

Relational Operators

OperatorDescriptionExpression
-eqChecks if the values of two operands are equal or not.
If yes, then the condition becomes true
[ $var1 -eq $var2 ] 
-neChecks if the values of two operands are equal or not.
If not, then the condition becomes true
[ $var1 -ne $var2 ] 
-gtChecks if the value of left is greater than the value of right.
If yes, then the condition becomes true
[ $var1 -gt $var2 ] 
-ltChecks if the value of left is less than the value of right.
If yes, then the condition becomes true
[ $var1 -lt $var2 ] 
-geChecks if the value of left is greater than or equal to the value of right.
If yes, then the condition becomes true
[ $var1 -ge $var2 ] 
-leChecks if the value of left is less than or equal to the value of right.
If yes, then the condition becomes true
[ $var1 -le $var2 ] 

File Test Operators

OperatorDescriptionExpression
-b fileChecks if the file is a block special file. If yes, the condition becomes true[ -b $file ] 
-c file Checks if the file is a character special file. If yes, the condition becomes true[ -c $file ] 
-d file Checks if the file is a directory. If yes, the condition becomes true[ -d $file ] 
-w fileChecks if the file is writable. If yes, the condition becomes true[ -w $file ] 
-x fileChecks if the file is executable. If yes, the condition becomes true[ -x $file ] 
-r fileChecks if the file is readable. If yes, the condition becomes true[ -r $file ] 
.
.
.
.
.
.
.
.
.

And there are a lot more. Explore them yourself.

Conditional Statements

This is shell decision-making. There are two types of decision-making statements:

  • if…else
  • case…esac

if…else statements

There are three types of if…else statements: if…fi, if…else…fi, if…elif…else…fi

  • if…fi

Syntax:

if [ expression ] 
then 
   Statement(s) to be executed if expression is true 
fi

Example:

#!/bin/sh
var1=10
var2=20

if [ $var1 == $var2 ]
then
   echo "var1 is equal to var2"
fi

if [ $var1 != $var2 ]
then
   echo "var1 is not equal to var2"
fi

Output:

var1 is not equal to var2
  • if…else…if

Syntax:

if [ expression ]
then
   Statement(s) to be executed if expression is true
else
   Statement(s) to be executed if expression is not true
fi

Example:

#!/bin/sh
var1=10
var2=20

if [ $var1 == $var2 ]
then
   echo "var1 is equal to var2"
else
   echo "var1 is not equal to var2"
fi

Output:

var1 is not equal to var2
  • if…elif…else…fi

Syntax:

if [ expression 1 ]
then
   Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
   Statement(s) to be executed if expression 2 is true
.
.
.
elif [ expression N ]
then
   Statement(s) to be executed if expression N is true
else
   Statement(s) to be executed if no expression is true
fi

Example:

#!/bin/sh
var1=10
var2=20

if [ $var1 == $var2 ]
then
   echo "var1 is equal to var2"
elif [ $var1 -gt $var2 ]
then
   echo "var1 is greater than var2"
elif [ $var1 -lt $var2 ]
then
   echo "var1 is less than var2"
else
   echo "None of the condition met"
fi

Output:

var1 is less than var2

case…esac Statements

case...esac statement is used when if…else statements are not the best solution. This is a similar statement to the switch…case statement in other languages like C, C++, etc.

Syntax:

case word in
   pattern1)
      Statement(s) to be executed if pattern1 matches
      ;;
   pattern2)
      Statement(s) to be executed if pattern2 matches
      ;;
.
.
.
   patternN)
      Statement(s) to be executed if patternN matches
      ;;
   *)
     Default condition to be executed
     ;;
esac

Example:

#!/bin/sh

COUNTRY="Nepal"

case "$COUNTRY" in
   "Nepal") echo "Nepal is famous for the Mt. Everest and Birthplace of Lord Buddha." 
   ;;
   "China") echo "China is famous for biggest and most populated country" 
   ;;
   "Australia") echo "Australia is famous for Sydney." 
   ;;
esac

Output:

Nepal is famous for the Mt. Everest and Birthplace of Lord Buddha.

Loops

A loop enables you to execute a set of commands repeatedly. for and while loops are the loops in Bourne Shell(Bash) scripting.

for Loops

for loops is used to iterate through a set of values.

Syntax:

for var in value1 value2 ... valueN
do
    Statement(s) to be executed for every word.
done

In the following example for loop is used to iterate through list words to print(echo) them one by one.

#!/bin/sh
for i in one two three four five
do
    echo $i
done

Output:

one
two
three
four
five

Try another example:

#!/bin/sh
for i in {1..5}
do
    echo $i
done

Output:

1
2
3
4
5

DIY:

#!/bin/sh
for FILE in $HOME/.bash*
do
    echo $FILE
done

while Loops

Using while loops you can check for a condition and loop until the condition is satisfied.

Syntax:

while command
do
   Statement(s) to be executed if command is true
done

Example:

#!/bin/sh
STRING = hello
while [ "$STRING" != "stop" ]
do
    echo "Please type something you want to print.(type stop to end)"
    read STRING
    echo "You typed: $STRING"
done
echo "stopped successfully!"

Output:

Please type something you want to print.(type stop to end)
hey
You typed: hey
Please type something you want to print.(type stop to end)
what is this?
You typed: what is this?
Please type something you want to print.(type stop to end)
stop
You typed: stop
stopped successfully!

You can use while : to make while condition always true(satisfied).

DIY:

#!/bin/bash
i=1
while [[ $i -le 10 ]] ; do
   echo "$i"
   (( i += 1 ))
done

Functions

Function in shell scripting enables you to break down functionality into smaller and logical parts which are called individually to perform specified tasks when needed.

The concept is similar to the function in other programming languages.

Syntax:

function_name () {
    list of commands
}

Example:

#!/bin/sh
# Function defining
greet () {
    echo "Good Morning"
}

# Calling the function
greet

Output:

Good Morning

Function with parameters

#!/bin/sh
# Function defining
greet () {
    echo "Good Morning, $1 and $2"
}

# Calling the function
greet Sagar Saroj

Output:

Good Morning, Sagar and Saroj

Return values from Function

#!/bin/sh
# Function defining
greet() {
    echo "Good Morning, $1 and $2"
    return 100
}

# Calling the function
greet Sagar Saroj

# Return value
return_value=$?
echo "Returned value is $return_value"

Output:

Good Morning, Sagar and Saroj
Returned value is 100

Nested Function

#!/bin/sh
# Calling one function from another
 func_one () {
   echo "This is from the first function."
   func_two
}

func_two () {
   echo "This is from the second function."
}

# Calling function one.
func_one

Output:

This is from the first function.
This is from the second function.

String Manipulation

String manipulation is changing strings or contents. Now, we’ll talk about some of the most useful string manipulations:

  • Concatenation of Strings

Syntax:

${string1}${string2}${string3}...

Example:

{
string="hello";
string2="world";
string3=${string}${string2};
echo ${string3}
}

Output:

helloworld
  • Listing of Strings in an Array

Syntax:

array(${strings} ${strings2} …)

Example:

{
strings=("hello" "world");
echo ${strings[@]}
}

Output:

hello world
  • Shorten a String
{
string="abcdefghijklmnopqrstuvwxyz";
for i in $( seq 0 $(( ${#string} - 1 )) );
do
    echo ${string:${i}};
done
}

Output:

abcdefghijklmnopqrstuvwxyz
bcdefghijklmnopqrstuvwxyz
cdefghijklmnopqrstuvwxyz
defghijklmnopqrstuvwxyz
efghijklmnopqrstuvwxyz
fghijklmnopqrstuvwxyz
ghijklmnopqrstuvwxyz
hijklmnopqrstuvwxyz
ijklmnopqrstuvwxyz
jklmnopqrstuvwxyz
klmnopqrstuvwxyz
lmnopqrstuvwxyz
mnopqrstuvwxyz
nopqrstuvwxyz
opqrstuvwxyz
pqrstuvwxyz
qrstuvwxyz
rstuvwxyz
stuvwxyz
tuvwxyz
uvwxyz
vwxyz
wxyz
xyz
yz
z
  • Capitalized the Whole String
string1=abcdefghijklmnopqrstuv
echo ${string1^^}

Output:

ABCDEFGHIJKLMNOPQRSTUV

DIY:

Explore more on string manipulations.