UNIT II
SHELL PROGRAMMING
What is Linux Shell
-Shell is a special program of the O.S which accepts the commands or Instructions from the user in English and if it is a valid command passes to the Kernel.
-Shell is a user program or it's environment provided for user interaction. ----Shell is an command language interpreter that executes commands read from the standard input device (keyboard) or from a file.
-Shell is not part of system kernel, but uses the system kernel to execute programs, create files etc.
Several shells available with Linux are
•
BASH (Most common shell in Linux. It's Freeware shell.)
• Developed by Brian Fox and Chet Ramey
•
CSH (
The C shell's syntax and usage are very similar to the C programming)• Developed by Bill Joy
•
Korn Shell (Developed at AT & T Bell Labs)
• Developed by David Korn
• TCSH(
TCSH is an enhanced but completely compatible version of the Berkeley UNIX C shell (CSH).
• Developed by Ken Greer at CMU-Carneige Mellon University
To find all supported shell by the system on which you are working The following command is used
$cat /etc/shells
Each shell does the same job, but each understand a different command syntax and provides different built-in functions.
To check you current shell use the following command
$echo $SHELL
Shell Variables
There are two types of shell variables
-
System variables
- Created and maintained by Linux itself. This type of variable defined in CAPITAL LETTERS.
-
User defined variables
Created and maintained by user. This type of variables are defined in lower letters.
You can see system variables by giving command like
$ set
System Variable Meaning
BASH=/bin/bash Our shell name
BASH_VERSION=1.14.7(1) Our shell version name
HOME=/home/vivek Our home directory
LOGNAME=students students Our logging name
OSTYPE=Linux Our Os type
PATH=/usr/bin:/sbin:/bin:/usr/sbin Our path settings
PWD=/home/students/Common Our current working directory
SHELL=/bin/bash Our shell name
USERNAME=vivek User name who is currently login to this PC
$ echo $USERNAME
$ echo $HOME
Exercise:
If you want to print your home directory location then you give command:
$ echo $HOME
How to define User defined variables (UDV)
To define UDV use following syntax Syntax:
variable name=value
'value' is assigned to given 'variable name' and Value must be on right side of = sign.
Example:
$ no=10 This is ok
$ 10=no Error, NOT Ok, Value must be on right side of = sign.
To define variable called 'vech' having value Bus
$ vech=Bus
To define variable called n having value 10
$ n=10
Rules for Naming variable name (Both UDV and System Variable)
(1) Variable name must begin with Alphanumeric character or underscore character (_), followed by one or more Alphanumeric character. For e.g. Valid shell variable are as follows HOMESYSTEM_VERSION
vechno
(2) Don't put spaces on either side of the equal sign when assigning value to variable. For e.g. In following variable declaration there will be no error
$ no=10
But there will be problem for any of the following variable declaration:
$ no =10
$ no= 10
$ no = 10
(3) Variables are case-sensitive, just like filename in Linux. For e.g.
$ no=10
$ No=11
$ NO=20
$ nO=2
Above all are different variable name, so to print value 20 we have to use $ echo $NO and not any of the following
$ echo $no # will print 10 but not 20
$ echo $No# will print 11 but not 20
$ echo $nO# will print 2 but not 20
(4) You can define NULL variable as follows (NULL variable is variable which has no value at the time of definition) For e.g.
$ vech=
$ vech=""
Try to print it's value by issuing following command
$ echo $vech
Nothing will be shown because variable has no value i.e. NULL variable.
(5) Do not use ?,* etc, to name your variable names.
How to print or access value of UDV (User defined variables)
To print or access UDV use following syntax Syntax:
$variablename
Define variable vech and n as follows:
$ vech=Bus
$ n=10
To print contains of variable 'vech' type
$ echo $vech
It will print 'Bus',To print contains of variable 'n' type command as follows
$ echo $n
Caution: Do not try $ echo vech, as it will print vech instead its value 'Bus' and $ echo n, as it will print n instead its value '10', You must use $ followed by variable name.
Exercise
Q.1.How to Define variable x with value 10 and print it on screen.
Q.2.How to Define variable xn with value Raj and print it on screen
Shell Arithmetic
To do sum or math operations in shell use expr, syntax is as follows Syntax:expr op1 operator op2
Where, op1 and op2 are any Integer Number (Number without decimal point) and operator can be
+ Addition - Subtraction / Division
% Modular, to find remainder For e.g. 20 / 3 = 6 , to find remainder 20 % 3 = 2, (Remember its integer calculation)
\* Multiplication
$ expr 6 + 3
Now It will print sum as 9 , But
$ expr 6+3
will not work because space is required between number and operator (See Shell Arithmetic)
Q.3.How to print sum of two numbers, let's say 10 and 5?
$expr 10 + 5
Q.4.How to define two variable x=20, y=5 and then to print division of x and y (i.e.
x/y)Q.5.Modify above and store division of x and y to variable called z
$ x=20
$ y=5
$ z=`expr x / y` (Back quotes)
$ echo $z
Let statement
Let command is used for assigning values to variable, it is same as expr but does not require $ sign with the variables.
Let x=10+15 echo $x
Or ((z=10+15)), set of double parenthesis may be used in place of let command.
bc :bench calculator To invoke bc use $bc 10/2*2 will produce 10
2.5*2.5+2 will produce 8.25 to get precise answer , use scale variable, which has to be set to number of digits after the decimal point.
$bc
Scale=1
25/2
12.5
Bc is also used for computing sin, cos, sqrt, tangent etc.
$bc sqrt(49)
For sin ,tan,cos etc invoke bc with –l
$bc –l s(3.14), c(2.5)
bc also permits setting up of variables
$bc
for(i=1;i<10;i++) I
1
2
3
.
.
Real Arithmetic
A=81.3
B=15.7
c=`echo $a + $b | bc`
d=`echo $a \* $b | bc`
echo $c $d
factor command is used to factorize a given number and print its prime factors
$ factor 28 will give 2, 2, 7
Reading input from users
Read variable name e.g read name
echo $name
– If constructs
– For loops
– While … do & Until … do loops
– Break & Continue commands
conditional Statements (if constructs ) if <condition>
then
### series of code goes here
fi
Double decision if <condition>
then
### series of code if the condition is satisfied else
### series of code if the condition is not satisfied fi
Multiple if condition if <condition1>
then
### series of code for condition1 elif <condition2>
then
### series of code for condition2 else
### series of code if the condition is not satisfied fi
Single-bracket syntax if [ condition ]
then
### series of code goes here fi
Double-bracket syntax if ((condition))
then
### series of code goes here fi
The single bracket syntax is the oldest supported syntax in bash shell. It is used together with all conditional statements in Linux.
Meanwhile, the double-parenthesis syntax is used for a number-based conditional statement to provide a familiar syntax to programmers. All types of if statements need a specified condition in order to execute a task.
Arithmetic-based Condition
The shell provides several ways in declaring an arithmetic-based condition. First is by using mnemonics that can be used together with the old-style single-bracket syntax and the other one is using mathematics-friendly symbols that can be used together with the double parenthesis
Below is the list of available mnemonics for arithmetic-based conditional statements in shell:
Operator Usage/Description -eq Equal
-ge Greater Than or Equal -gt Greater Than
-le Less Than or Equal -lt Less Than
-ne Not Equal
String-based Condition
Making decisions based on a string user-input is also possible in the bash shell. The string-based condition returns a binary expression as a result meaning, it returnstrue if the specified condition is satisfied
otherwise, it returns false. The following are the commonly-used string-based conditional operators:
Operator Description
== Returns true if the strings are equal
!= Returns true if the strings are not equal
-n Returns true if the string to be tested is not null -z Returns true if the string to be tested is null
Let's create a sample script using string-based conditional statement. The script will allow the user to input two strings and assess whether one of the strings is null, both string are equal and not equal.
read -p "First String: " str1 read -p "Second String: " str2 if [ -z "$str1" ]
then
echo "The 1st string is null"
elif [ -z "$str2" ] then
echo "The 2nd string is null"
else
if [ $str1 == $str2 ] then
echo "The strings are equal"
else
echo "The strings are not equal"
fi fi
File-based condition
File-based conditions are unary expressions and often used to examine a status of a file. The following list shows the most commonly used file-based conditions in the bash shell.
OperatorDescription -a file Returns true if file exists
-b file Returns true if file exists and is a block special file -c file Returns true if file exists and is a character special file -d file Returns true if file exists and is a directory
-e file Returns true if file exists
-r file Returns true if file exists and is readable
-s file Returns true if file exists and has a greater size that zero -s file Returns true if file exists and has a greater size that zero -w file Returns true if file exists and is writable
-x file Returns true if file exists and is executable
-N file Returns true if the file exists and has been modified since it was last read
cd ls
if [ -e sample.sh ] then
echo "file exists!"
else
echo "file does not exist"
fi
Script to test whether a file exists or not and to check its permissions cd
ls -l
read -p "Enter a file name: " filename if [ -e $filename ]
then
echo "file exists!"
if [ -r $filename ] then
status="readable "
fi
if [ -w $filename ] then
status=$status"writable "
fi
if [ -x $filename ] then
status=$status"executable"
fi
echo "file permission: "$status else
echo "file does not exist"
fi
The for loop is a looping statement that uses the keyword for to declare a repetitive statement. The bash supports different syntaxes for the for loop statement:
for <varName> in <list>
do
#### your statement here done
This syntax starts with the keyword for, then followed by a variable name, the keyword in and the list of possible values for the variable.Each value in the list will be separated with a space and the start of the code lines that will be repeated is defined in the do and ends with a done keyword.
result=0;
input=0;
for var in 1 2 3 4 5 do
printf "Input done integer %d : " $var read input
result=$((result+input)) done
echo "the result is " $result
C-like Syntax
for((initialization; boolean_test; increment/decrement)) do
#### your code goes here done
Example script result=0
input=0
for((var=1;var<=5;var++)) do
printf "Input integer %d : " $var read input
result=$((result+input)) done
echo $result
While Structure with Arithmetic Symbols based conditional statements The while statement is a type of repetitive structure in bash that utilizes the keyword while. Unlike the C-type syntax of for looping structure, the while repetitive control structure separates the initialization, Boolean test and the increment/decrement statement.
<initialization>
while(condition) do
###your code goes here
<increment/decrement>
done
Example script result=0
input=0 var=1
while((var <= 5)) do
printf "Input integer %d : " $var read input
result=$((result+input)) var=$((var+1))
done
echo "the result is " $result
While Looping Statement with mnemonic based conditional statement
<initialization>
while [ <condition> ] do
####your code goes here
<increment/decrement>
done
Sample Script var=1;
while [ $var -le 5 ] do
printf "Input integer %d : " $var read input
result=$((result+input)) var=$((var+1))
done
echo "the result is " $result
While Looping Statement with File-based Conditional Statement while read <variable_name>
do
####your code goes here done <<path to the text file>
Create a file data having the names of sub directories to be created, data file must be present in sample
mkdir sample cd sample
echo "creating directories..."
while read var do
mkdir $var done<data
Alias command alias l=‘ ‘
$l
Positional parameters and command line arguments
Information can be passed into script via command line. Each word separated by a space following the script name is called argument.
$0 refers to script name
$1 refers to first argument
$2 refers to second argument
$# refers to number of parameters
$* refers to complete argument list
Set command
The set command with arguments reset positional parameters.
Once reset the old parameter list is lost.
Example:
Set Aligarh Delhi London will set $0 as Aligarh, $1 as Delhi To unset use
set- -
This will remove the parameter list.
Set ‘apple pie’ pears peaches for i in $*
do echo $i done
apple
pie
pears
peaches
Set ‘apple pie’ pears peaches for i in “$@”
do echo $i done
apple pie
pears
peaches
The $* and $@ differ only when enclosed between double quotes. When $* is enclosed between double quotes, the parameter list becomes a single string and when $@ is enclosed between double quotes , each word is treated as a separate string.
Shift Command
The shift command shifts the parameter list to the left a specified number of times. The shift command without an argument shifts the parameter list once to the left, once the list is shifted the parameter is permanently removed.
Format shift n
Set Aligarh Agra Delhi Mumbai Shift
Echo $* --- > Agra Delhi Mumbai Shift
Echo $* --- > Delhi Mumbai Set `date`
Echo $* Fri Sep 9 10:00:05 PDT 2004 Shift 5
Echo $* 2004 While test $# -gt 0 Echo $*
Shift Done Doit 1 2 3 4 5 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
An array is a variable containing multiple values may be of same type or of different type. There is no maximum limit to the size of an array.
Declaring an Array and Assigning values
In bash, array is created automatically when a variable is used in the format like,
name[index]=value
name is any name of an array
index could be any number or expression that must evaluate to a number greater than or equal to zero.
Unix[0]='Debian'
Unix[1]='Red hat'
Unix[2]='Ubuntu'
Unix[3]='Suse'
echo ${Unix[1]}
Red hat
To access an element from an array use curly brackets like
${name[index]}.
Initializing an array during declaration
Instead of initializing an each element of an array separately, you can declare and initialize an array by specifying the list of elements (separated by white space) with in a curly braces.
Syntax
declare -a arrayname=(element1 element2 element3)
If the elements has the white space character, enclose it with in a quotes.
declare -a Unix=('Debian' 'Red hat' 'Red hat' 'Suse' 'Fedora');
declare -a declares an array and all the elements in the parentheses are the elements of an array.
Print the Whole Bash Array
There are different ways to print the whole elements of the array. If the index number is @ or *, all members of an array are referenced. You can traverse through the array elements and print it, using looping statements in bash.
echo ${Unix[@]}
Debian Red hat Ubuntu Suse
Referring to the content of a member variable of an array without providing an index number is the same as referring to the content of the first element, the one referenced with index number zero.
Length of the Bash Array
We can get the length of an array using the special parameter called $#.
${#arrayname[@]} gives you the length of the array.
declare -a Unix=('Debian' 'Red hat' 'Suse' 'Fedora');
echo ${#Unix[@]} #Number of elements in the array
echo ${#Unix} #Number of characters in the first element of the array.i.e Debian 4
6
Length of the nth Element in an Array
${#arrayname[n]} should give the length of the nth element in an array.
Unix[0]='Debian' Unix[1]='Red hat' Unix[2]='Ubuntu' Unix[3]='Suse'
echo ${#Unix[3]} # length of the element located at index 3 i.e Suse 4
Extraction by offset and length for an array
The following example shows the way to extract 2 elements starting from the position 3 from an array called Unix.
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
echo ${Unix[@]:3:2}
Suse Fedora
The above example returns the elements in the 3rd index and fourth index. Index always starts with zero.
Extraction with offset and length, for a particular element of an array To extract only first four elements from an array element . For example, Ubuntu which is located at the second index of an array, you can use offset and length for a particular element of an array.
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
echo ${Unix[2]:0:4}
Ubun
The above example extracts the first four characters from the 2nd indexed element of an array.
Search and Replace in an array elements
The following example, searches for Ubuntu in an array elements, and replace the same with the word ‘SCO Unix’.
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
echo ${Unix[@]/Ubuntu/SCO Unix}
Debian Red hat SCO Unix Suse Fedora UTS OpenLinux
In this example, it replaces the element in the 2nd index ‘Ubuntu’ with ‘SCO Unix’. But this example will not permanently replace the array content.
Add an element to an existing Bash Array The following example shows the way to add an element to the existing array.
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Unix=("${Unix[@]}" "AIX" "HP-UX") echo ${Unix[7]}
AIX
In the array called Unix, the elements ‘AIX’ and ‘HP-UX’ are added in 7th and 8th index respectively.
Copying an Array
Expand the array elements and store that into a new array as shown below.
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Linux=("${Unix[@]}") echo ${Linux[@]}
Debian Red hat Ubuntu Fedora UTS OpenLinux Concatenation of two Bash Arrays
Expand the elements of the two arrays and assign it to the new array.
Unix=('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Shell=('bash' 'csh' 'jsh' 'rsh' 'ksh' 'rc' 'tcsh');
UnixShell=("${Unix[@]}" "${Shell[@]}") echo ${UnixShell[@]}
echo ${#UnixShell[@]}
Debian Red hat Ubuntu Suse Fedora UTS OpenLinux bash csh jsh rsh ksh rc tcsh 14
It prints the array which has the elements of the both the array ‘Unix’ and ‘Shell’, and number of elements of the new array is 14.
declare –a x=(1 2 3 4 5)
for((i=0;i<=${#x[@]};i++)) do
echo ${x[i]}
done