Module 2-Os
Module 2-Os
TYPES OF SHELL
1) Thompson Shell
First UNIX shell
Introduced by Ken Thompson in1971 at Bell Lab.
Simple command interpreter
Not designed for scripting
Led to the development of the later UNIX command shells.
Does not have command history and value prompt
Provides the basic features including piping, simple control
structures using if and goto
2) Bourne Shell (sh)
Introduced by Stephen Bourne at Bell Labs in 1977
Remains a useful shell today as the default root shell
Source code was developed in C
Served 2 primary goals:-
i. Executing UNIX/LINUX commands for the OS ie,
Command-Line Interpreter.
ii. Writing reusable scripts that could be invoked through
the shell ie, Scripting
It replaces the Thompson Shell by offering many features such
as control flows, loops, and variables into scripts, providing a
more functional language to interact with the OS.
Path in UNIX file system hierarchy is /bin/sh
3) C Shell (csh)
Developed by Bill Joy in 1978
For achieving a scripting language similar to C programming
language
Easier and faster to use
Introduced many features including editing mechanism, aliases,
directory stack, cd path
Uses the “%” as a prompt
Can also read commands from a file, called a script
Support all of the features that the Bourne shell supports and
has a more natural syntax for programming
4) TENEX C Shell (tcsh)
Developed by Ken Greer in 1979
Based on & compatible with C shell
Can be used as an interactive shell login & shell script
command processor
Provide the following features:-
C like syntax
Command-line editor
Programmable word & file name completion
Spelling correction
5) Korn Shell (ksh)
Developed by David G Korn at Bell Labs in 1980
Combined features of both Bourne & C shell
Complete, powerful, high-level programming language and
also an interactive command language.
Provides the following features:-
Floating-point arithmetic
Command aliasing & history
Associative array
6) Bourne-Again Shell (bash)
Developed by Brian Fox in 1989 for the GNU Project
Developed as a pre-software replacement for the Bourne Shell
It showed all features from the Bourne Shell but is much more
efficient & easy to use
Provides the following features:-
Command-line editing
Unlimited size command history
Shell functions & aliases
Unlimited size indexed arrays
SHELL SPECIAL CHARACTERS
~ Home Directory:-
The tilde (~) is shorthand for your home directory. It means
you don‟t have to type the full path to your home directory in
commands. Wherever you are in the file system, you can use
this command to go to your home directory:
cd ~
. Current Directory:-
A period (.) represents the current directory. You see it in
directory listings if you use the -a (all) option with ls:
ls -a
You can also use the period in commands to represent the
path to your current directory. For example, if you want to
run a script from the current directory, you would call it like
this:
./script.sh
.. Parent Directory:-
The double period or “double dot” (..) represents the parent
directory of your current one. You can use this to move up
one level in the directory tree.
cd ..
# Comment:-
Most often, you use the hash or number sign (#) to tell the
shell what follows is a comment
The grep command searches a file or files for lines that have a
certain pattern. The syntax is –
Example Script
Assume we create a test.sh script. Note all the scripts would have
the .sh extension. Before you add anything else to your script, you
need to alert the system that a shell script is being started. This is done
using the shebang construct. For example −
#!/bin/sh
This tells the system that the commands that follow are to be
executed by the Bourne shell. It's called a shebang because the #
symbol is called a hash, and the ! symbol is called a bang.
#!/bin/bash
pwd
ls
Shell Comments
#!/bin/bash
# Shell Scripting
# Script follows here:
pwd
ls
$chmod +x test.sh
Upon execution, you will receive the following result –
/home/User
index.html
test.sh
new.txt
Note − To execute a program available in the current directory,
use ./program_name
Note: In the last step you have to mention the path of the script if
your script is in other directory.
The following script uses the read command which takes the input
from the keyboard and assigns it as the value of the variable
PERSON and finally prints it on STDOUT.
#!/bin/sh
# Script follows here:
echo "What is your name?"
read PERSON
echo "Hello, $PERSON"
Here is a sample run of the script –
$./test.sh
What is your name?
Zara Ali
Hello, Zara Ali
Variable Names
_ALI
TOKEN_A
VAR_1
VAR_2
Following are the examples of invalid variable names –
2_VAR
-VARIABLE
VAR1-VAR2
VAR_A!
The reason you cannot use other characters such as !, *, or - is that
these characters have a special meaning for the shell.
Defining Variables
NAME="Zara Ali"
The above example defines the variable NAME and assigns the value
"Zara Ali" to it. Variables of this type are called scalar variables. A
scalar variable can hold only one value at a time. Shell enables you to
store any value you want in a variable. For example −
VAR1="Zara Ali"
VAR2=100
Accessing Values
To access the value stored in a variable, prefix its name with the
dollar sign ($). For example, the following script will access the value
of defined variable NAME and print it on STDOUT –
#!/bin/sh
NAME="Zara Ali"
echo $NAME
The above script will produce the following value –
Zara Ali
Read-only Variables
#!/bin/sh
NAME="Zara Ali"
readonly NAME
NAME="Qadiri"
The above script will generate the following result –
Unsetting Variables
unset variable_name
The above command unsets the value of a defined variable. Here is a
simple example that demonstrates how the command works –
#!/bin/sh
NAME="Zara Ali"
unset NAME
echo $NAME
The above example does not print anything. You cannot use the unset
command to unset variables that are marked readonly.
Variable Types
Special Variables
Command Line Arguments
However, the "$*" special parameter takes the entire list as one
argument with spaces between and the "$@" special parameter takes
the entire list and separates it into separate arguments.
We can write the shell script as shown below to process an
unknown number of command line arguments with either the
$* or $@ special parameters –
#!/bin/sh
for TOKEN in $*
do
echo $TOKEN
done
Here is a sample run for the above script –
array_name[index]=value
Here array_name is the name of the array, index is the index of the
item in the array that you want to set, and value is the value you
want to set for that item.
Suppose you are trying to represent the names of various students
as a set of variables. Each of the individual variables is a scalar
variable as follows –
NAME01="Zara"
NAME02="Qadir"
NAME03="Mahnaz"
NAME04="Ayan"
NAME05="Daisy"
Accessing Array Values
After you have set any array variable, you access it as follows −
${array_name[index]}
Here array_name is the name of the array, and index is the index of
the value to be accessed. Following is an example to understand the
concept –
#!/bin/sh
NAME[0]="Zara"
NAME[1]="Qadir"
NAME[2]="Mahnaz"
NAME[3]="Ayan"
NAME[4]="Daisy"
echo "First Index: ${NAME[0]}"
echo "Second Index: ${NAME[1]}"
The above example will generate the following result –
$./test.sh
First Index: Zara
Second Index: Qadir
You can access all the items in an array in one of the following
ways –
${array_name[*]}
${array_name[@]}
Here array_name is the name of the array you are interested in.
Following example will help you understand the concept –
#!/bin/sh
NAME[0]="Zara"
NAME[1]="Qadir"
NAME[2]="Mahnaz"
NAME[3]="Ayan"
NAME[4]="Daisy"
echo "First Method: ${NAME[*]}"
echo "Second Method: ${NAME[@]}"
The above example will generate the following result –
$./test.sh
First Method: Zara Qadir Mahnaz Ayan Daisy
Second Method: Zara Qadir Mahnaz Ayan Daisy
Basic Operators
Assume a variable file holds an existing file name "test" the size of
which is 100 bytes and has read, write and execute permission on −
Decision Making
1) If-else statement
2) case-esac statement
1) If-else statement
1) if-fi
2) if-else-fi
3) if-elif-else-fi
4) nested if-else
if-fi
Syntax:
if [ expression ]; then
statements
fi
Example:
Name="Satyajit"
if [ "$Name" = "Satyajit" ]; then
echo "His name is Satyajit. It is true."
fi
Output:
if-else-fi
Syntax:
if [ expression ]
then
statement1
else
statement2
fi
Example:
Age=17
if [ "$Age" -ge 18 ]; then
echo "You can vote"
else
echo "You cannot vote"
fi
Output:
if-elif-else -fi
Syntax:
if [ expression1 ]
then
statement1
statement2
.
.
elif [ expression2 ]
then
statement3
statement4
.
.
else
statement5
fi
Example:
Age=17
if [ "$Age" -ge 18 ]; then
echo "You can vote"
elif [ "$Age" -eq 17 ]; then
echo "You can vote after one year"
else
echo "You cannot vote"
fi
Output:
nested if-else
Syntax:
if [ expression ]
then
statement1
if [ expression ]
then
statement
else
statement
fi
else
statement2
fi
Example:
if [ $subject == 'Linux' ]
then
echo "Enter Marks"
read marks
if [ $marks -ge 30 ]
then
echo "You passed"
else
echo "You failed"
fi
else
echo "Wrong Subject"
fi
Output 1:
Enter subject
Linux
Enter Marks
97
You passed
Output 2:
Enter subject
Linux
Enter Marks
29
You failed
Output 3:
Enter subject
DBMS
Wrong Subject
String-Based Condition
Arithmetic-Based Condition
2) case-esac statement
case-esac is basically working the same as switch statement in
programming. Sometimes if we have to check multiple conditions,
then it may get complicated using if statements. At those moments
we can use a case-sac statement. The syntax will be:
case $var in
Pattern 1) Statement 1;;
Pattern n) Statement n;;
esac
Example:
Name="Satyajit"
case "$Name" in
#case 1
"Rajib") echo "Profession : Software Engineer" ;;
#case 2
"Vikas") echo "Profession : Web Developer" ;;
#case 3
"Satyajit") echo "Profession : Technical Content Writer" ;;
esac
Output:
Loops
1. while statement
2. for statement
3. until statement
while statement
One of the easiest loops to work with is while loops. They say,
while an expression is true, keep executing these lines of code.
Syntax:
Example:
Output:
for statement
The for loop is a little bit different to the previous two loops. What
it does is say for each of the items in a given list, perform the given
set of commands.
Syntax:
Example:
Output:
Ranges
We can also process a series of numbers
Output:
When specifying a range you may specify any number you like for
both the starting value and ending value. The first value may also
be larger than the second in which case it will count down.
It is also possible to specify a value to increase or decrease by each
time. You do this by adding another two dots ( .. ) and the value to
step by.
Output:
until statement
The until loop is fairly similar to the while loop. The difference is
that it will execute the commands within it until the test becomes true.
Syntax:
Example:
Output:
Nesting Loops
All the loops support nesting concept which means you can put one
loop inside another similar one or different loops. This nesting can
go up to unlimited number of times based on your requirement.
Here is an example of nesting while loop. The other loops can be
nested based on the programming requirement in a similar way −
Nesting while Loops:
It is possible to use a while loop as part of the body of another
while loop.
Syntax:
Example:
Output:
0
1 0
2 1 0
3 2 1 0
4 3 2 1 0
5 4 3 2 1 0
6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
8 7 6 5 4 3 2 1 0
9 8 7 6 5 4 3 2 1 0
Controlling Loops: Break and Continue
Most of the time your loops are going to through in a smooth and
orderly manner. Sometimes however we may need to intervene and
alter their running slightly. There are two statements we may issue to
do this.
break
The break statement is used to terminate the loop and can be used
within a while, for, and until.
Syntax:
break [N]
// N is the number of nested loops.
// This parameter is optional.
// By default the value of N is 1.
Example:
Output:
Value of j is 1
As the value of break is 2, when the value of j is 2, both the loops
are exited in a single step. So, the only value of j is printed when it
was 1.
continue
Continue is a command which is used to skip the remaining
command inside the loop for the current iteration in for, while, and
until loop.
Syntax:
continue [N]
// the optional parameter N specifies the nth enclosing loop to
continue from.
// This parameter is optional.
// By default the value of N is 1.
Example:
Output:
value of j is 1
value of j is 1
value of j is 1
value of j is 1
value of j is 1