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
Operator | Description | Expression |
+ (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
Operator | Description | Expression |
! | Inverts the condition | [ ! false ] |
-o | Logical OR. If one is true then the whole condition becomes true | [ $var1 -lt 20 -o $var2 -gt 100 ] |
-a | Logical AND. If both are true then the whole condition becomes true | [ $var1 -lt 20 -a $var2 -gt 100 ] |
String Operators
Operator | Description | Expression |
= | The condition becomes true if two operands are equal | [ $str1 = $str2 ] |
!= | The condition becomes true if two operands are not equal | [ $str1 != $str2 ] |
-z | Checks whether string operand size is zero or not. If zero, it returns true | [ -z $str1 ] |
-n | Checks if string operand size is non-zero. If non-zero, it returns true | [ -n $str1 ] |
str | Checks if str is not an empty string. If empty, it returns false | [ $str1 ] is not false |
Relational Operators
Operator | Description | Expression |
-eq | Checks if the values of two operands are equal or not. If yes, then the condition becomes true | [ $var1 -eq $var2 ] |
-ne | Checks if the values of two operands are equal or not. If not, then the condition becomes true | [ $var1 -ne $var2 ] |
-gt | Checks if the value of left is greater than the value of right. If yes, then the condition becomes true | [ $var1 -gt $var2 ] |
-lt | Checks if the value of left is less than the value of right. If yes, then the condition becomes true | [ $var1 -lt $var2 ] |
-ge | Checks 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 ] |
-le | Checks 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
Operator | Description | Expression |
-b file | Checks 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 file | Checks if the file is writable. If yes, the condition becomes true | [ -w $file ] |
-x file | Checks if the file is executable. If yes, the condition becomes true | [ -x $file ] |
-r file | Checks 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.