Introduction:
Why shell programming? A working knowledge of shell scripting is essential to everyone wishing to become reasonably adept at system administration, even if they do not anticipate ever having to actually write a script. When a Linux machine boots up, init process is initiated first then it executes the shell scripts in /etc/rc.d to restore the system configuration analyzing the behavior of a system, and possibly modifying it [Kernigham].
Writing shell scripts is not hard to learn, since only a fairly small set of shell-specific operations and options are to be learned.
What is a shell:
The shell is the art of UNIX that is most visible to the user. It receives and interprets the commands entered by the user. In many respects, this makes it the most important component of the UNIX structure. It is certainly the part that we, as users, get to know the most. To do anything in the system, we must give the shell a command. If the command requires a utility, the shell requests that the kernel execute the utility. If the command requires an application program, the shell requests that it be run.
There are two major parts to a shell. The first is the interpreter. The interpreter reads your commands and works with the kernel to execute them. The second part to the shell is a programming capability that allows you to write a shell (command) script. A shell script is a file that contains shell commands that perform a useful function. It is also known as a shell program.
Shell types:
There are 4 major types of shells are used in UNIX today.
1. Bourne Shell (sh)
2. C Shell (csh)
3. Korn Shell (ksh)
4. Bourne Again Shell (bash)
The Bourne shell, developed by Steve Bourne at the AT&T Labs, is the oldest. Because it is the oldest and most primitive, it is not used on many systems today.
The C shell, developed in Berkeley by Bill Joy, received its name from the fact that its commands were supposed to look like C statements. A compatible version of the C shell, tcsh is used in Linux.
The Korn shell, developed by David Korn, also of the AT&t Labs, is the newest and most powerful. Because it was developed at the AT&T Labs, it is compatible with the Bourne shell.
The Bourne Again Shell, developed by Steve Bourne at the AT&T Labs. This shell is widely used with in the academic community. bash provides all the interactive features of the C shell (csh) and the Korn shell (ksh).
Shell types diagram
|
Shell Responsibilities:
· Program Execution
· Variables & File name substitution
· I/O Redirection
· Pipeline Hookup
· Environment control
· Interpreted programming Language.
Program Execution:
The shell is responsible for the execution of all programs that you request from your terminal. Each time you type in a line to the shell, the shell analyzes the line and then determines what to do. The line that is typed to the shell is known more formally as the command line. The shell scans this command line and determines the name of the program to be executed and what arguments to pass to the program.
Variable and Filename Substitution:
Like any other programming language, the shell lets you assign values to variables. Whenever you specify one of these variables on the command line, preceded by a dollar sign, the shell substitutes the value assigned to the variable at that point.
I/O Redirection:
It is the shell’s responsibility to take care of input and output redirection on the command line. It scans the command line for the occurrence of the special redirection characters <, >, or >>.
Pipeline Hookup:
Just as the shell scans the command line looking for redirection characters, it also looks for the pipe character |. For each such character that it finds, it connects the standard output from the command preceding the | to the standard input of the one following the |. It then initiates execution of both programs.
Environment Control:
The shell provides certain commands that let you customize your environment. Your environment includes home directory, the characters that the shell displays to prompt you to type in a command, and a list of the directories to be searched whenever you request that a program be executed.
Interpreted Programming Language:
The shell has its own built-in programming language. This language is interpreted, meaning that the shell analyzes each statement in the language one line at a time and then executes it. Programs developed in interpreted programming languages are typically easier to debug and modify than compiled ones.
Pipes:
We often need to use a series of commands to complete a task. For example, if we need to see a list of users logged into the system, we use the who command. However, if we need a hard copy of the list, we need two commands. First, we use who to get the list and store the result in a file using redirection.
We can avoid the creation of the intermediate file by using a pipe ( | ). Pipe is an operator that temporarily saves the output of one command in a buffer that is being used at the same time as the input of the next command. The first command must be able to send its output to standard output; the second command must be able to read its input from standard input.
General command line is as follows:
Command1 | Command2 | Command3 | Command4
Eg : $who > user.lst
$ wc -l < user.lst
(or)
$ who | wc -l
Note : Pipe is an operator, not a command. It tells the shell to immediately take the output of the first command, which must be sent to standard output, and turn it into input for the second command, which must get its input from standard input.
Redirection:
Redirection is the process by which we specify that a file is to be used in place of one of the standard files. With input files, we call it input redirection; with output files, we call it output redirection.
Input Redirection:
Some commands are designed to take their input as a stream. This stream represents the standard input to a command. Standard input stream has 3 sources:
1. File
2. Keyboard (default)
3. Pipe line
3 Sources of Standard Input
Eg : $ wc -l < user.lst
Output Redirection:
When we redirect standard output, the command’s output is copied to a file rather than displayed on the monitor. There are two basic redirection operators for standard output: > & >>. The default redirection output is terminal.
If you want the file to contain only the output from this execution of the command, you use one greater than token (>). In this case, when you redirect the output to a file that doesn’t exist, UNIX creates it and writes the output.
Eg: $ who > sample
On the other hand, if you want to append the output to the file, the redirection token is two greater than characters (>>). Think of the first greater than as saying you want to redirect the output and the second one as saying that you want to go to the end of the file before you start outputting. When you append output, if the file doesn’t exist, UNIX creates it and writes the output. If it already exists, however, UNIX moves to the end of the file before writing any new output.
Eg : $ cat file2 >> file1
Disadvantages of I/O Redirection:
· Creation of temporary files
· Memory wastage
· Process time becomes slow
Here Document (<<):
A here document is a special-purpose code block. It uses a form of I/O redirection to feed a command list to an interactive program or a command, such as ftp, cat or the ex text editor.
Eg :
$ tr a-z A-Z << end
> mca
> year
> end
Output: MCA YEAR
Shell as a Programming Language:
A shell script is a script written for the shell, or command line interpreter, of an operating system. It is often considered a simple domain-specific programming language. Typical operations performed by shell scripts include file manipulation, program execution, and printing text. Group of commands stored in a file is called shell script or shell program.Shell scripts are slower than compiled programs, but speed is not a constraint with certain jobs. Shell scripts are not recommended for number crunching. System administrator tasks are often best handled by shell scripts.
The activities of the shell are not restricted to command interpretation alone. The shell has a whole set of internal commands that can be strung together as a language – with its own variables, conditionals and loops.
Shell meta characters :
There are some special characters that are recognized by the shell. Here are some that you will often:
File substitution:
* – This is a ‘wildcard’, it matches any string of zero or more characters, except a leading ‘.’
Eg: ls *.txt
This will list all the files in the current directory that end with a .txt
? – This will match any single character.
Eg: ls file?.txt
This will find the files such as file1.txt, file2.txt etc.
I/O Redirection:
> – to redirect standard output to a file
< – to take input from standard input devices
<< – to give input from the terminal
>> – to redirect output and append a file which contain data
Process Execution : (;)
; – It is used to execute more than one command.
Eg : $ date ; cat file1
() – It is used to grouping morethan one command.
Eg : #(date;cat file) ; ls
& – to execute commands in background mode
Eg : $ ls &
&& – If we pass two commands for this if first command is successfully executed then only it will execute the second command.
Eg : $ ls file && echo file found
|| – it will executes second command if first command fails.
Eg: $ ls file || echo not found
Quoting :
(back slash): it negates the special property of the single character followed it
Eg: echo *
It neglects the properties of * and displays the * as output
‘ ‘ : Negates the special properties of all enclosed characters
Eg: $ x=hello
$ echo ‘ < > $x ? & ‘
The output is : < > $x ? &.
“ “ : Negates the special properties of all enclosed characters except $, ` ,
Eg: $ x=hello
$ echo “< > $x ? & “
The output is : < > hello ? &.
Positional parameters:
These are used to pass the parameter for shell script programs.
$0 – name of the command or script name
$* or $@ –gives list of arguments
$# – gives number of arguments
$1,$2,… – first argument and second argument respectively.
Special parameters:
$$ – gives the PID of the current shell
$? – gives the exit status of the last executed command
$! – gives PID of the last background process
$- – gives the current setting of shell.
Shell variables:
A variable is a location in memory where values can be stored. Each shell allows us to create, store, and access values in variables. Each shell variable must have a name. The name of a variable must start with an alphabetic or underscore (_) character. It then can be followed by zero or more alphanumeric or underscore characters. There are two broad classifications of variables: user-defined and predefined.
Variables diagram
|
User-defined variables:
User defined variables are not separately defined in UNIX. The first reference to a variable establishes it. The syntax for storing values in variables is the same for the Korn and Bash shells, but it is different for the C Shell.
Eg: $x=10
$ echo $x
Output : 10.
$ x=UNIX
$ y=$x
$ echo $y
Output : UNIX.
For removing variables which we are defined syntax is
$ unset variablename
Predefined variables:
Predefined variables are used to configure a user’s shell environment. For example, a system variable determines which editor is used to edit the command history. Other systems variables store information about the environment. For example, a system variable contains the pathname to home directory.
Predefined variables can be divided into two categories: shell variables and environmental variables. The shell variables are used to customize the shell itself. The environmental variables control the user environment and can be exported to sub shells.
$set is used to display all predefined variables available in shell.
Shell Commands:
read: Read values for variables; white space separated words
Eg: $ read name
Paul
$ echo $name
Output: Paul
set: Display the values of all shell/system variables or predefined values and set is also used to assign values to the positional parameters.
Eg: $ set `date`
$ echo $@ or echo $*
Output: Thu Sep 8 18:08:40 EDT 2011
$ echo $1
Output: Thu
$ shift 1 // this command is used for shifting to next field
$ echo $1
Output: Sep
Eg: $ set `cat f1`
$ echo $#
$ echo $2
#: Used for comments in Shell Programming
printf: printf command is used to print the code formats just like in your C
Eg: printf “sum is : %d” 100
Output : 100
expr: expr performs four basic arithmetic operations and the modulus function. It handles only integers, decimal portions are simple truncated or ignored.
$x=3 y=5
$expr 3 + 5
output: 8
$expr $x + $y
output: 8
$z=`expr $x + $y` ; echo $z
output: 8
$x=`expr $x + 1`
$echo $x
output: 4
The Environment:
An important UNIX concept is the environment, which is defined by environment variables. These variables control the behavior of the system. Some are set by the system, others by you, yet others by the shell, or any program that loads another program. $env command displays only environment variables
Variable Significance
HOME home directory
PATH Search path for commands
USER login name
LOGNAME as above
TERM Terminal type
SHELL Users login shell
Control Structures:
Conditional Control Structures:
if, if-else, elif, case
1. if: if command is executed if it test condition is true
Syntax : if command is successful
then
Command
fi
2. if-else: if-else executes an action if the exit status of its test command is true; if
false, then the else action is executed.
Syntax : if command is successful
then
command
else
command
fi
command
else
command
fi
3. elif: elif allows you to nest if structures, enabling selection among several
alternatives; at the first true if structure, its commands are executed and
control leaves the entire elif structure.
Syntax: if command is successful
then
command
elif command is successful
command
elif command is successful
then
command
else
command
fi
command
else
command
fi
Using test or [ ] to Evaluate Expressions:
The if conditional can’t handle relational tests directly, but only with assistance of the teststatement. test uses certain operators to evaluate the condition on its right and returns an exit status, which is used by if for making decisions. test works in 3 ways:
- Compares two numbers (like test $x –gt $y or [ $x –gt $y ]).
- Compares two strings or a single one for a null value (like test $x = $y).
- Checks a file’s attributes (like test –f $file).
Numerical comparison operators used with test:
Operator Meaning
-eq Equal to
-ne Not equal to
-gt Greater than
-ge Greater than or equal to
-lt Less than
-le Less than or equal to
String tests with test:
Test True if
s1 =s2 String s1 = s2
s1 != s2 String s1 is not equal to s2
-n stg String stg is not a null string
-z stg String stg is a null string
stg String stg is assigned and not null
s1 == s2 String s1 = s2 (Korn and Bash only)
File Attribute Testing with test:
Test True If File
-f file file exists and is a regular file
-r file file exists and is a readable
-w file file exists and is a writable
-x file file exists and is executable
-d file file exists and is a directory
-s file file exists and has a size greater than zero
-e file file exists (korn & bash only)
-L file file exists and is a symbolic link (korn & bash only)
f1 -nt f2 f1 is newer than f2 (korn & bash only)
f1 -ot f2 f1 is older than f2 (korn & bash only)
f1 -ef f2 f1 is linked to f2 (korn & bash only)
Eg: if [ -e file ]
then
echo “File exists”
fi
4. case: case matches the string value to any of several patterns. If a pattern is matched, its associated commands are executed.
Syntax: case expression in
pattern 1) command 1;;
pattern 1) command 1;;
pattern 2) command 2;;
*) command;;
esac
Eg: echo -e “Menu n 1. List of files n 2. Todays Date n 3. Users n 4. Exit n
Enter your choice: ”
read choice
case $ choice in
1) ls;;
2) date;;
3) who;;
4) exit;;
*) echo “Invalid Option”
esac
Loop Control Structures: while, for and until
1. While: while executes an action as long as its test command is true.
Syntax: while condition is true
do
command
done
do
command
done
Eg: while [ $x -eq $y ]
do
echo $x
done
2. For in: for-in is designed for use with lists of values; the variable operand is
consecutively assigned the values in the list.
Syntax: for variable in list
do
command
done
do
command
done
Eg: for i in 1 2 3
do
echo $i
done
Output: 1 2 3
3. Until : until executes an action as long as its test command is false.
Syntax: until command
do
command
done
do
command
done
Eg: until [ $x -eq $y ]
do
echo $x
done
break: break is designed for breaking the looping statements
Eg: for i in 1 2 3 4 5
do
if [ $ i -eq 3 ]; then
break;
fi
echo $i
done
Output: 1 2
continue:continue is designed to continue the loop at specific condition
Eg: for i in 1 2 3 4 5
do
if [ $ i – eq 3 ]; then
continue;
fi
echo $i
done
Output: 1 2 4 5
Shell Script Example:
echo PROGRAM TO FIND BIGGEST OF 3 NUMBERS
echo Enter 3 numbers
read a
read b
read c
if [ $a -ge $b ] && [ $a -ge $c ]
then
echo $a is big
elif [ $b -ge $c ]
then
echo $b is big
else
echo $c is big
fi