UNIX Module-4
UNIX Module-4
Shell Scripts
2
The shell’s interpretive cycle
When the user log on to the system the Unix command runs at the terminal till the user log out. This
command is the shell.
Even though the shell appears not to be doing anything meaningful when there is no activity at the
terminal, it swings into action the moment you key in something.
3
The shell’s interpretive cycle
These are special characters that mean nothing to the command, but mean something
special to the shell.
cat>foo
ls | more
rm –r *
• When the shell sees metacharacters like the >, |, *, etc. in its input, it translates these
symbols to their respective actions before the command is executed.
• It replaces the * with almost all filenames in the current directory (but skips hidden files)
so that rm ultimately runs with these names as arguments.
• On seeing the >, the shell creates a file foo and and connects cat’s output to it.
• The shell re-creates the command line by removing all metacharacters and finally passes
on the command to the kernel for execution.
4
The shell’s interpretive cycle
The following activities are typically performed by the shell in its interpretive cycle:
• The shell issues the prompt and waits for you to enter a command.
• After a command is entered, the shell scans the command line for metacharacters and it
expands abbreviations (like the * in rm *) to recreate a simplified command line.
• It then passes on the command line to the kernel for execution.
• The shell waits for the command to complete and it can’t do any work while the command is
running
• After the command execution is complete, the prompt reappears and the shell return to its
waiting role to start next cycle.
5
Shell offerings
Here we consider the shells belonging to two categories:
1. The Bourne family comprising the Bourne shell (bin/sh) and its derivatives the Korn
shell (bin/ksh) and Bash (bin/bash).
2. The C Shell (bin/csh) and its derivative, Tcsh (bin/tcsh).
To see which shell is running and it’s absolute pathname run the command : $ echo
$SHELL
6
Pattern Matching – The Wild-Cards
Often you may need to enter multiple filenames in a command line. For example,
If filenames are similar, we can use the facility offered by the shell.
Metacharacters are used to construct the pattern for matching filenames are called wild-cards.
7
Pattern Matching – The Wild-Cards
• In Unix shell programming, a wild card (or wildcard) is a character or a string used to represent a
group of characters. It is often used in commands to specify multiple files or directories that match a
certain pattern.
• Here are some commonly used wildcards:
* (asterisk) : Matches zero or more characters in a filename.
? (question mark) : Matches any single character in a filename.
[ ] (brackets) : Matches any one of the enclosed characters.
9
10
Pattern Matching – The Wild-Cards
1) * and ?
$ ls chap*
(lists all the filenames in the current directory starting from ‘chap).
$ echo *
$ ls emp*lst
$ ls chap?
(It matches total 5 characters here.ie; chap and one character after chap).
The * does not match all files beginning with a .(dot) or the /
$ ls .???*
(Here it lists all the hidden filenames whose filename contain minimum 3 characters). 12
Pattern Matching – The Wild-Cards
3) The Character Class []:
It is used for restrictive listing i.e. we can list only the selected filenames from the current directory.
The character class contains a set of characters enclosed by the rectangular brackets, like [and], but it
matches a single character in the class.
$ ls chap0[123]
13
Pattern Matching – The Wild-Cards
Range specification is also possible inside the class with a - (hyphen); the two characters on either
side of it form the range of characters to be matched.
Negating the Character Class (!) : This property doesn’t work in C shell.
i) *.[!co] - Matches all filenames with a single-character extension but not the .c or .o files.
ii) [!a-zA-Z]* - Matches all filenames that don't begin with an alphabetic character.
14
Pattern Matching – The Wild-Cards
4) Matching Totally Dissimilar Patterns{ }:
This feature, is not available in the Bourne shell, enables us to match totally dissimilar patterns.
i) To copy all the C and Java source programs from another directory to your current directory.
$ cp $HOME/prog_sources/*.{c,java} .
Note: Delimit the patterns with a comma, and then put curly braces around them (don’t include
spaces)
ii) Using the curly brace form, you can also access multiple directories.
$ cp /home/kumar/{project,html,scripts}/* .
This copies all files from three directories (project, html and scripts) to the current directory.
15
Pattern Matching – The Wild-Cards
5) Rounding up:
– Some of the wild-card characters have different meanings depending on where they are placed in
the pattern
* and ? Lose their meaning when used inside class, and are matched literally
- and ! Also lose their significance when placed outside the class.
16
Pattern Matching – The Wild-Cards
• * and ?: These are powerful wildcards that lose their special meaning inside a character
class.
• For example, in [a*] , the asterisk is treated as a literal character rather than a wildcard.
• Outside of a class, * means "match zero or more characters," and ? means "match exactly
one character."
17
Escaping and Quoting
The shell uses some special characters to match the filenames, if the filenames themselves
has these special characters it would be dangerous.
$ ls chap*
chap chap* chap01 chap02 chap03 chap04 chap15 chap16 chap17 chapx
So, now trying rm chap* would be dangerous.
We must protect all special characters so that shell is unable to interpret them, Shell
provides two solutions to prevent this:
1. Escaping (\)
Providing a \(backslash) before the wild-card ($rm chap\*) to remove its special meaning
2. Quoting (‘ ’)
Enclosing wild-card or even the entire pattern within quotes (like ‘chap*’) anything within
these quotes are left alone and not interpreted.
18
1. Escaping
Just placing ‘\’ before a metacharacter, Special meaning can be removed and shell treats it literally as
character.
The \ suppresses the wild-card nature of the *, thus preventing the shell from performing filename
expansion on it. This feature is known as escaping.
$ echo>chap0\[1-3\]
19
1. Escaping (cont’d)
Escaping the space
$ ls my\ progs.txt
20
1. Escaping (cont’d)
Escaping the \ itself:
$ echo \\
\
$ echo \\n
\n
Escaping the newline character:
$ echo “it is used to evaluate shell \[enter]
>variables and to display the message.”
Escaping in echo:
It uses \t,\n as escape sequences.
The \ has a reverse meaning; it treats the characters n and t as special rather than
remove their special meanings.
21
2. Quoting
• The pattern which is enclosed within the quotes looses it’s special meaning.
• Double and single quotes are used here.
$ echo ‘\’ displays a \
$ rm ‘chap*’ removes file chap*
$ rm “My Document.doc” removes file My Document.doc
• Escaping is tedious affair when there are too many characters to protect, so quoting is
better solution.
The single quotes protect all special characters. Double quotes, however, let a pair of
backquotes (` `) be interpreted as command substitution characters, and the $ as a variable
prefix. There is also a reciprocal relationship between the two types of quotes; double quotes
protect single quotes, and single quotes protect double quotes. 23
Redirection : The three standard files
In the context of redirection the terminal is a generic name that represents the screen,
display or keyboard
The shell associates three files with the terminal two for display and one for keyboard
Even though our terminal is also represented by a specific device name (/dev/tty –
teletype) , commands don’t usually read from or write to this files.
The shell performs all terminal related activity in these three files that the shell makes
available to every command.
24
Redirection : The three standard files
The special files are streams (sequence of bytes) of characters which many commands
see as input and output.
When user logs in, the shell makes available the three files representing three streams
Each stream is associated with the default device, and generally speaking-this device is
the terminal.
25
Redirection : The three standard files
1)Standard input : The file representing input, which is connected to the keyboard
2)Standard output : The file representing output, which is connected to the display
3)Standard error : The file representing error message that emanate from the command or
shell. This is also connected to the display.
Even though the shell associates each of these files with a default physical device, this
association is not permanent
The shell can unhook a stream from its default device and connect it to a disk file the
moment it see some special characters ( > and < ) in the command line
26
1)Standard input:
We have used the cat and wc commands to read disk files.
These commands have an additional method of taking input. i.e. when they are used
without arguments, they read file representing the standard input.
It has three input sources:
i) The default source, keyboard
ii) The file using redirection with the < symbol
iii) Another program using pipeline (|)
27
1)Standard input:
$ wc
Standard input can be redirected, It can come from a file or a pipeline [ctrl-d] (give
input from the keyboard)
The shell can reassign the standard input to a disk file, ie; changing the default source.
$ wc < file1.txt
When shell sees < symbol, it opens the disk file ‘file1.txt’.
It unplugs standard input file from it’s default source & assigns to ‘file1.txt’
wc reads from standard input which is reassigned by the shell to file1.txt
28
Taking input both from file & standard input:
When a command takes input from multiple sources - say a file and standard input, the
symbol ‘−’ is used to indicate the sequence of taking input.
$ cat - foo
First from standard input then from the file foo
$ cat foo - bar
First from foo, then standard input, and then bar
29
2)Standard output:
All commands display output on the terminal but actually they write to standard output file
as a stream of characters not directly to the terminal.
30
2)Standard output (cont’d)
The default destination can be changed using >
$ wc file1.txt > file2.txt
Here, the first command sends word count of file1.txt to file2.txt, but nothing will appear on the
terminal screen.
$ cat file2.txt (It displays the word count of file1.txt)
When shell sees > symbol, it opens the file file2.txt for writing.
If the output file doesn’t exist, the shell creates it before executing the command.
It unplugs the standard output file from it’s default destination & assigns it to file2.txt.
If it exists, the shell overwrites it, so use the > operator with caution.
$ wc file1.txt >> file2.txt does not disturb existing contents
31
2)Standard output (cont’d)
The shell also provides the >> symbol used for appending file.
$ wc file1.txt >> file2.txt
Redirection also becomes useful when concatenating the standard output of a number of files
$ cat *.c > c_progs.txt
(ls –x *.c ; echo; cat *.c) > c_progs.txt
32
3)Standard error:
All three standard files are represented by a number called the file descriptor.
A file is opened by referring its path name, but subsequent read and write operations identify the file
by the file descriptor.
Kernel maintains a table of file descriptors for every process running in the system.
0 : standard input
1 : standard output
2 : standard error
The descriptors are implicitly prefixed to the redirection symbols. For instance > and 1> mean the
same, while < and 0< also are identical.
If your program opens a file, then the file will be allocated the descriptor 3.
33
3)Standard error:
To handle standard error streams file descriptor should be specified explicitly.
The default destination of standard error stream is the terminal itself.
$ cat foo
cat: cannot open foo // ERROR MESSAGE
cat command tries to open foo & writes to standard error.
34
3)Standard error (cont’d)
• While redirecting the standard error stream to a file, The file descriptor should be
specified explicitly along with the output redirection symbol.
• Redirecting standard error requires the use of the 2> symbols.
$ cat foo 2> newfile
$ cat newfile
cat:cannot open foo
$ cat foo.sh > bar1 2>bar2 For saving both the streams in the same file.
35
Filters : using both standard input and standard output
From the viewpoint of using standard input and standard output, UNIX commands can be
grouped into four categories:
1. Directory oriented commands (cd, mkdir, rmdir) and basic file handling commands
(cp, mv, rm) use neither standard input nor standard output.
2. Commands like ls, pwd, who etc. don’t read standard input but they write to
standard output.
3. Commands like lp (line printer) that reads standard input but don’t write to standard
output.
4. Commands like cat, wc, od, cmp, gzip etc. use both standard input and standard
output. Such Commands are called filters. Most filters can read directly from files whose
names are provided as arguments.
36
Filters : using both standard input and standard output
37
Filters : using both standard input and standard output
$ cat calc.txt
2^2
25*50
$ bc < calc.txt > result.txt bc (basic calculator) command line calculator
$ cat result .txt
4
1250
Though we used < first and then the >, there is no restriction in the sequence of use or in the
whitespace around the symbol.
$ bc > result.txt < calc.txt
$ bc>result.txt<calc.txt So all the commands are same
$ > result.txt < calc.txt bc
38
/dev/null AND /dev/tty: Two special files
/dev/null, you’ll like to check whether a program runs successfully without seeing its output on the
screen.
You may not want to save this output in the file either. Thus, you have a special file that simply
accepts any stream without growing in size– the file /dev/null.
$ cat /dev/null
This facility is useful in redirecting error messages away from the terminal so they don’t
appear on the screen.
/dev/null simply accepts(absorbs or burns out) all input written to it, and the file size remains zero.
39
/dev/null AND /dev/tty: Two special files (cont’d)
/dev/tty is a second special file in the UNIX system that indicates one’s terminal.
who>/dev/tty
It means that /dev/tty is a separate entity from the typical standard input (stdin), standard output
(stdout), and standard error (stderr) streams.
While stdin, stdout, and stderr are the default streams that handle input from the keyboard and output
to the terminal (or other devices), /dev/tty provides a direct interface to the terminal itself.
40
Connecting Commands: Pipe (|)
$ who > user.txt
$ cat user.txt
1. For long running commands the process can be slow. The second command cannot act unless
the first command has completed its job.
2. An intermediate file is needed and that has to be removed after the completion of the job. Large
temporary files use up the disk space. who’s standard output was redirected, so was wc’s
standard input and both used the same disk file.
Eg: $ who | wc -l
Here, the output of who has been passed directly as input to ‘wc’, and who is said to be piped to
‘wc’.
$ ls | wc –l
ls | wc –l > fkount piped command output can be redirected
ls | more
42
Connecting Commands: Pipe (|) (cont’d)
You can run a large number of commands in a pipeline, the number being restricted to the maximum
number of processes that can be run by a non-root user.
But you must know the behavioral properties of these commands to place them there.
Consider this command sequence, which prints the man page of grep on the printer:
43
Connecting Commands: Pipe (|) (cont’d)
• When a sequence of commands is combined together in this way, a pipeline is formed. The shell
sets up this interconnection; the commands have no knowledge of it.
• The pipe is the third source and destination of standard input and standard output, respectively.
• You can now use one to count the number of files in the current directory:
$ ls | wc -l
15
44
Connecting Commands: Pipe (|) (cont’d)
Consider this command sequence, which prints the man page of grep on the printer:
man grep: This displays the manual page for the grep command, providing detailed information on
its usage, options, and examples.
| (pipe): The pipe operator passes the output of the previous command (in this case, the man grep
output) as input to the next command.
col -b: This command removes backspaces and ensures that the output is clean and formatted for
printing. The -b option removes all backspace characters.
| lp: The lp command sends the final output to the printer. This prints the man grep manual, with
backspaces removed, directly from your terminal.
45
When a command needs to be ignorant of its source
At times commands needs to be ignorant of source and destination
$ wc -c *.c
6 1.c
53 p2.c
40 p3.c
0 p4.c
99 total
• The display shows the total usage in bytes, but it also shows the usage for each file.
• We are not interested in individual statistics this time, what we need is a single figure representing
the total size. To be able to do that, you must make wc ignorant of its input source.
• You can do that by feeding the concatenated output stream of all these files to wc -c as its input:
$ cat *.c | wc -c
99
• Since wc acts on a stream this time, it displays a single figure.
46
tee command
• The tee command in Unix is used to read from standard input and write to both standard output and
one or more files simultaneously.
• It allows you to redirect the output of a command or a series of commands to a file while still
displaying it on the terminal.
• The basic syntax of the tee command is as follows:
ls | tee output.txt
-a (or --append): Appends the output to the specified files rather than overwriting them.
ls | tee -a output.txt
tee: creating a tee
The comparison succeeds, who’s output and the contents saved earlier by tee are identical.
Command Substitution
The shell enables the connecting of two commands in yet another way.
While a pipe enables a command to obtain its standard input from the standard output of another
command, the shell enables one or more command arguments to be obtained from the standard
output of another command.
Note:
• ` (backquote) and $ will be evaluated inside the “ ” double quotes. i.e. ` (backquote) and $ is
interpreted by the shell when placed within double quotes.
• Command substitution is enabled when backquotes are used within double quotes.
• Whereas, ` (backquote) and $ will not be evaluated inside the ‘ ’ single quotes. The metacharacters
are printed as it is when used with echo command.
51
Shell Variables
Programmers should note that there must not be any whitespace on either side of the = symbol.
The command line x =5 is interpreted by the shell as the x command running with the =5 argument!
Variable names begin with a letter but can contain numerals and the _ as the other characters.
Names are case-sensitive; x and X are two different variables. Unlike in programming languages,
shell variables are not typed; you don’t need to use a char, int, or long prefix when you define them.
In fact, you don’t even have to declare them before you can
use them. All shell variables are of the string type, which means that even a number like 123 is
stored as a string rather than in binary.
52
Shell Variables
All shell variables are initialized to null strings by default. But we can assign it explicitly as null
using .
x=“ ” or x=‘ ’ or x=
A variable can be removed with unset and protected from reassignment by readonly.
$ unset x # x is now undefined
$ readonly x # x cant be reassigned
53
Effects of Quoting and escaping
• To assign a multiword string to a variable, you can escape each space character, but quoting
(single or double) is preferred solution:
• There is another special character ($) that is gobbled up by the shell, you may still need to
interpret it without being evaluated, using escaping and single-quoting as the options:
$ echo The average pay is \$1000
The average pay is $1000
$ echo ‘The average pay is $1000’
The average pay is $1000
54
Effects of Quoting and escaping (Cont’d)
Like the backquote, the $ is also evaluated by the shell when it is double quoted. Here are two
examples:
$ echo “The path is $PATH and the current directory is `pwd`”
The path is /bin:/usr/bin:. and the current directory is /home/kumar/workc
In the first example, both command substitution and variable evaluation works.
Note:
Whether you should use double quotes or single quotes depends on whether you want
command substitution and variable evaluation to be enabled or not.
55
Environment variables
Shell variables are of two types: local and environment.
PATH, HOME and SHELL are environment variables.
They are so called because they are available in the user's total environment like in the sub-shells
that run shell scripts, and mail commands and editors.
Local variables are more restricted.
$DOWNLOAD_DIR=/home/kumar/download
$ echo $DOWNLOAD_DIR
/home/kumar/download
DOWNLOAD_DIR local variable; its value is not available to child processes.
Run a Bourne sub-shell with sh and check whether you can see the variable or not:
$ sh Create a child shell .
$ echo $DOWNLOAD_DIR
Now, check whether Path is visible or not
56
Environment variables
$ echo $PATH
PATH=/bin:/usr/bin:.:/usr/ccs/bin
$ exit
$_
The set statement displays all variables available in the current shell, but the env command
displays only environment variables.
$ env The command set lists all shell variables, including
environment and local variables, functions, and shell
options.
57
The Common Environment Variables:
Variable name Stored information
HOME Path to your home directory
PATH Search paths for commands
SHELL Current shell
PS1 Primary prompt
PS2 Secondary prompt
HOSTNAME Local host name
LOGNAME Login name
MAIL Location of your incoming mail folder
PWD Present working directory
TERM Terminal type
UID User
58
Where to use shell variables
Setting pathnames: If a pathname is used several times in a script, you should assign it to a
variable. You can then use it as an argument to any command.
$ progs=‘/home/kumar/c_progs’
$ cd $progs ; pwd
/home/kumar/c_progs
Using command substitution: You can also use the feature of command substitution to set
variables:
$ mydir=`pwd` ; echo $mydir
/home/kumar/c_progs
We used the < symbol to leave out the filename in the value assigned to size. If we had used
foo.txt as an argument instead, then size would have contained a two-word string.
59
Where to use shell variables (Cont’d)
Concatenating variables and strings: Variable concatenation is simple; no special operators
or symbols are needed. Simply place the variables side by side:
60
How the shell processes the command
• Parsing: The shell first breaks up the command line into words using spaces and tabs as delimiters,
unless quoted. All consecutive occurrences of a space or tab are replaced here with a single space.
• Variable evaluation: All $-prefixed strings are valuated as variables, unless quoted or escaped.
• Command Substitution: Any command surrounded by the backquotes is executed by the shell,
which then replaces the standard output of the command into the command line.
• Redirection: The shell then looks for the characters >, < and >> to open the files they point to.
• Wild-card interpretation: The shell finally scans the command line for the wild-cards. Any word
containing the wild-card is replaced by a sorted list of filenames that match the pattern. The list of
filenames then forms the arguments to the command.
• PATH evaluation: If finally looks for the PATH variable to determine the sequence of directories it
has to search inorder to hunt for the command.
61
MODULE 4:
ESSENTIAL SHELL PROGRAMMING
Chapter 14
62
Essential shell Programming
The shell program discussed here focus on basic shell which is Bourne shell.
There are some advanced features for Korn and Bash Shells.
The shell program runs in interpretive mode.
It is not compiled into a executable file as a C program.
Each statement is to be loaded into the memory when it is to be executed.
Shell consequently runs slower than the high level languages.
interpretive mode means interpreter reads the source code of the program and executes it directly,
translating each statement into machine code or intermediate code on the fly.
63
Shell scripts
When groups of command have to be executed regularly, they should be stored in a file and
executed as a shell script or a shell program.
Shell scripts are executed in a separate child shell process and this sub shell need not be of
same type as your login shell (i.e. even if your login shell is bourne, you can use a Korn sub-shell
to run your script).
By default, the child and parent shells belongs to the same type, but user can provide a special
interpreter line in the first line of the script to specify a different shell for your script.
64
Shell scripts
• The .sh extension is commonly used to denote shell scripts.
• Shell scripts are text files containing commands written in a shell programming language,
such as the Bourne Shell (sh), Bash (bash), Zsh (zsh), or others.
• The .sh extension helps identify these files as shell scripts, making it easier for users and the
system to recognize and handle them appropriately.
• When a file has a .sh extension, it typically indicates that it contains a series of shell
commands that can be executed sequentially.
• For example, if you have a file named myscript.sh, you would typically expect it to be a
shell script that you can execute in a Unix-like environment using a shell interpreter such as
sh or bash.
65
Shell scripts
Example: script.sh
#!/bin/sh
# script.sh: Sample Shell Script
echo “Welcome to Shell Programming”
echo “Today’s date : `date`”
echo “This months calendar:” cal `date “+%m 20%y”` #This month’s calendar.
echo “My Shell : $SHELL”
The # character indicates the comments in the shell script and all the characters that follow the #
symbol are ignored by the shell. However, this does not apply to the first line which begins with #.
This because, it is an interpreter line which always begins with #! followed by the pathname of
the shell to be used for running the script.
In the above example the first line indicates that we are using a Bourne Shell.
66
Shell scripts
To run the script we need to first make it executable using the chmod command
$ chmod +x script.sh
Then invoke the script name as:
$ script.sh ./script.sh
You can also explicitly spawn a child of your choice with the script name as argument:
$ sh script.sh //will spawn a bourne shell
67
Read: Making scripts interactive
• The read statement is the shell’s internal tool for making scripts interactive (i.e. taking
input from the user).
• It is used with one or more variables.
• Inputs supplied with the standard input are read into these variables.
• Use of statement like
read name
• The script pauses to take input from keyboard.
• Whatever we enter is stored in a variable name
echo name
• Since this is a form of assignment, no $ is used before name.
68
Read: Making scripts interactive
• The script pauses to take input from keyboard.
#! /bin/sh
# emp1.sh: Interactive version, uses read to accept two inputs
#
echo “Enter the pattern to be searched: \c”
read pname
echo “Enter the file to be used: \c”
read fname
echo “Searching for pattern $pname from the file $fname”
grep “$pname” $fname
echo “Selected records shown above”
69
Read: Making scripts interactive
$ emp1.lst
OUTPUT
Enter the pattern to be searched : director
Enter the file to be used: emp.lst
Searching for pattern director from the file emp.lst
9876|JaiSharma|Director|Production|12/03/50|7000
2356|Rohit |Director|Sales |11/05/47|7800
Selected records shown above
cat emp.lst
2233|a.k.shukla|g.m.|sales|12/12/52|6000
9876|jai sharma|director|production|12/03/50|7000
5678|sumit chakrobarty|d.g.m.|marketing|04/19/43/6000
2356|Rohit |Director|Sales|11/05/47|7800
5423|n.k. gupa|chairman|admin|08/30/56|5400 70
grep
• grep is a command-line utility used for searching text patterns in files. It stands for "Global Regular
Expression Print".
• grep searches for lines matching a specified pattern in one or more files or from the standard input,
and prints those lines.
• Here's a basic usage of grep:
grep pattern filename
Therefore they can be run non interactively and be used with redirection and pipelines.
When arguments are specified with a shell script, they are assigned to special shell
variables rather Positional parameters $1, $2, etc;
72
#include <stdio.h>
arg.c
int main(int argc, char *argv[]) {
// Print the number of arguments
printf("Number of arguments: %d\n", argc);
return 0;
}
73
Save the code to a file, say args.c. Output:
Compile the program:
Number of arguments: 4
gcc args.c -o args
Argument 0: ./args
Argument 1: first
Run the executable with some arguments: Argument 2: second
./args first second third Argument 3: third
74
Command Line Arguments
additional shell parameters are listed as follows:
$# Number of arguments specified in command line
$0 Name of the executed command
$* Complete set of positional parameters as a single string
When multiword string is used to represent a single command line argument, it is required to quote it.
Example:
#! /bin/sh
# emp2.sh: Non-interactive version – uses command line arguments
echo “program: $0
The number of arguments specified is $#
The arguments are $*”
grep “$1” $2
echo “\nJob Over”
$emp2.sh director emp.lst 75
The additional special parameters used by shell.
Positional Parameter Description
$0 The name of the script or command
$1 to $9 The first to ninth positional parameters
The tenth and subsequent positional parameters, using braces to avoid conf
${10} and beyond
usion with positional parameters $1 through $9
Any positional parameter where n is a number, accessed via ${n} for value
$n
s beyond $9
$* All positional parameters as a single word
$@ All positional parameters as separate words
$# The number of positional parameters
$$ The process ID of the current shell
$? The exit status of the last executed command
$- The current options set for the shell
$_ The last argument of the previous command
76
exit and Exit status of command
To terminate a program exit is used.
exit 0 used when everything went fine.
exit 1 used when something went wrong.
Not necessary to place this statement at the end of every shell script. Often used with the command
when it fails.
Every command returns an exit status to the caller.
Nonzero value indicates an error condition.
Example 1:
$ cat foo
cat: can’t open foo
Returns nonzero exit status.
The shell variable $? stores this status exit status of the last command.
It has the value nonzero if it fails and zero if it succeeds.
77
exit and Exit status of command
Example 2:
$ grep director emp.lst > /dev/null; echo $?
0 (Success)
• Exit status is used to devise program logic that branches into different paths depending on success
or failure of a command.
78
The logical Operators && and ||
The shell provides two operators that allow conditional execution, the && and ||.
Usage:
cmd1 && cmd2
cmd1 || cmd2
&& delimits two commands. cmd2 executed only when cmd1 succeeds.
Example1: $ grep ‘director’ emp.lst && echo “Pattern found”
Output:
1006|chanchal singhvi|director|sales|03/09/38|6700
6521|lalit chowdury|director|marketing| 26/09/45|8200
Pattern found
|| this indicates inverse role , the second command executed only first command fails.
Example 2: $ grep ‘clerk’ emp.lst || echo “Pattern not found”
Output:
Pattern not found
79
The if Conditional
• The if statement makes two way decision depending on the fulfillment of a certain condition.
• Form 1:
if command is successful
then Form 3:
execute commands if command is successful
then
else
execute commands
execute commands elif commands is successful
fi then
execute commands
elif . . ....
• Form 2:
else
if command is successful execute commands
then fi
execute commands
fi
80
The if Conditional
The condition placed in the command line of the if statement will henceforth be referred as the
control command.
Example: emp3.sh
#! /bin/sh
if grep “^$1” /etc/passwd 2>/dev/null
then
echo “Pattern Found”
else
echo “Pattern Not Found”
fi
$emp3.sh ftp
$emp3.sh mail
81
Using test and [ ] to Evaluate Expressions
When if is used to evaluate expressions, test statement is required because the true or false values
returned by expressions cant directly handled by if.
Test uses certain operators to evaluate the condition on its right and returns either a true or false exit
status, which is then used by if for making decisions.
Test does not display any output it simply set the parameter
$?.
82
Numeric Comparison
Operators always begin with a – (Hyphen) followed by a two letter word and enclosed on either
side by white space.
Numeric comparison in the shell is confined to integer values only, decimal values are simply
truncated.
Note that, you must provide a whitespace around the operators and operands and inside [ and ].
In C, if(x) means x is greater than 0, same way we can use if [ $x ] as shorthand of
if [ $x –gt 0 ].
85
String Comparison
Test can be used to compare strings with set of operators
Equality is performed with = (s1 = s2)
Inequality != (s1 != s2)
–z string is a null string (–z stg)
–n string is not a null string (–n stg)
Negation ! (! –n stg)
[! –z $string] : negates [-z $string]
Test also permits checking of more than one condition in the same line using the –a (AND) and –o
(OR) operators
if [– n “$pname” –a –n “$fname” ] ; then
emp3a.sh “$pname” “$fname”
else
echo “At least one input was a null String”; exit 1
fi 86
String Comparison
Example: emp4.sh fi
#!/bin/sh emp31.sh “$pname” “$flname”
#emp1.sh checks user input for null values finally turns else
emp.sh developed previously emp31.sh $*
# fi
if [ $# –eq 0 ] ; then
Output1:
echo “Enter the string to be searched :\c”
$emp4.sh
read pname Enter the string to be searched :[Enter]
if [ –z “$pname” ] ; then You have not entered the string
echo “You have not entered the string”; exit 1 Output2:
fi $emp4.sh
echo “Enter the filename to be used :\c” Enter the string to be searched :root
read flname Enter the filename to be searched
:/etc/passwd
if [ ! –n “$flname” ] ; then
Root:x:0:1:Super-user:/:/usr/bin/bash
echo “ You have not entered the flname” ; exit 2 87
File tests
Test can be used to test the various file attributes like its type(file, directory or symbolic link) or its
permissions (read, write, execute etc.)
-f file exists and is a regular file
-e file exists
88
File tests
Example:
$ ls –l emp.lst
-rw-rw-rw- 1 kumar group 870 jun 8 15:52 emp.lst
90
The case Conditional
• The statement matches an expression for more than one alternative, and uses compact
construct to permit multiway branching.
• Syntax:
case expression in
Pattern1) commands1 ;;
Pattern2) commands2 ;;
Pattern3) commands3 ;;
...
esac
91
The case Conditional
• Example: menu.sh
#! /bin/sh
#
echo “ Menu\n
1. List of files\n2. Processes of user\n3. Today’s Date
4. Users of system\n5.Quit\nEnter your option: \c”
read choice
case “$choice” in
1) ls –l;;
2) ps –f ;;
3) date ;;
4) who ;;
5) exit ;;
*) echo “Invalid option” #;; not required for last option
92
esac
Matching Multiple Patterns
Case can also specify the same action for more than one pattern .
For instance to test a user response for both y and Y (or n and N).
Example:
read ans
case “$ans” in
Y | y ) ;;
N | n) exit ;;
esac
93
Wild cards *, ?, [] : case uses them
Cases uses the string matching using wild-cards.
The metacharacters *, ?, [] can be used to match only strings not file names in current directory.
case “$answer” in
[yY][eE] [sS]*) ;;
[nN][oO]) exit ;;
esac
94
expr : Computation
Shell can check whether an integer is greater than other but it does not have any computing features
It relies on external command expr for computation
expr can perform the four basic arithmetic operations (+, -, *, /), as well as modulus (%)
functions.
Examples:
$ x=3 y=5
$ expr 3+5
8
$ expr $x-$y
-2
$ expr 3 \* 5
Note:\ is used to prevent the shell from interpreting * as metacharacter
15
$ expr $y/$x
95
expr : String handling
• The expr command is a versatile tool in UNIX for string handling and manipulation.
• 1. Length of a String:
string="Hello World"
length=$(expr length "$string")
echo "Length: $length“
• Substring Extraction:
string="Hello World"
# Extract 5 characters starting from the 7th position
substring=$(expr substr "$string" 7 5)
echo "Substring: $substring"
96
expr : String handling
• The expr command is a versatile tool in UNIX for string handling and
manipulation.
• 3. String Index: Substring Extraction:
string="Hello World" # Find the position of the first occurrence of 'W’
index=$(expr index "$string" "W")
echo "Index: $index“
• Match a Regular Expression:
string="Hello World" # Match the first word
match=$(expr match "$string" '\([A-Za-z]*\)’)
echo "Match: $match"
97
expr : String handling
• 5. Remove Part of a String:
filepath="/home/user/documents/file.txt"
# Remove the file part, leaving the directory path
parentdir=$(expr "$filepath" : '\(.*\)/[^/]*')
echo "Parent Directory: $parentdir“
Define filepath: The variable filepath contains the absolute path of the file.
Extract Parent Directory: parentdir=$(expr "$filepath" : '\(.*\)/[^/]*')
expr evaluates the expression.
'\(.*\)/[^/]*': This is the regular expression that will match and capture the portion of
the string before the last / (the directory part).
Print Parent Directory: The echo command outputs the parent directory.
98
\(.*\): This captures everything before the last /. It matches any character (.) zero or
more times (*), and the parentheses \( \) are used to capture this part.
/[^/]*: This matches the part after the last /. It matches the / followed by any
sequence of characters that are not / (denoted by [^/]*), which corresponds to the file
name.
The regular expression matches the entire string, but the expr command extracts
only the portion that is captured in the parentheses (\(.*\)), which is the part before
the last /.
The result will be the path to the directory, excluding the file name.
99
while : Looping
Loops allows to perform a set of instructions repeatedly
It repeatedly performs a set of instructions until the control command returns true exit status
do
commands
done
100
#!/bin/sh
#emp5.sh shows the use of while loop
#
answer =y # must set it to y first to enter the loop
while [ “$answer” = “y” ] #the control command
do
echo “Enter the code and description: \C” > /dev/tty
read code description # read both together
echo “$code |$description” >> newlist # Append a newline to list
echo “ Enter any more(y/n)? \c” > /dev/tty
read anymore
case $anymore in
y*|Y*) answer=y ;; #Also accepts yes, YES etc.
n*|N*) answer=n ;; #Also accepts no, NO etc
*) answer=y ;; #Any other reply means y
esac
101
done
/dev/tty is not doing anything special.
Note that you added a record to newlist with the >> symbol.
This causes newlist to be opened everytime echo is called up.
The shell provides redirection facility at the done keyword itself to avoid multiple file opening and
closures.
done>>newlist
You need infinite loop, and its best implemented using true as a dummy control command with
while.
true does nothing except return a true exit status. Another command named false returns a false
value.
while true;
do
df –t # df reports the free space in the disk
sleep 300
done & #& after done runs loop in background
103
for: Looping with a List
• for does not test a condition but uses a list
• Syntax: for variable in list
do
Commands #loop body
done
• Each whitespace-separated word in list is assigned to variable in turn, and the commands are executed until
list is exhausted.
• Example:
$for file in ch1 ch2; do
> cp $file ${file}.bak
> echo $file copied to $file.bak
>done
Output:
ch1 copied to ch1.bak
ch2 copied to ch2.bak
104
Sources of list
• List from variables: Series of variables are evaluated by the shell before executing the loop
Example:
$ for var in $PATH $HOME; do echo “$var” ; done
• Output:
/bin:/usr/bin;/home/local/bin;
/home/user
• List from command substitution: Command substitution is used for creating a list. This is used
when list is large.
Example:
$ for var in `cat clist`
105
Sources of list
• List from wildcards: Here the shell interprets the wildcards as filenames.
Example:
for file in *.lst ; do
grep “director” $file
done
• List from positional parameters: for is also used to process positional parameters that are assigned
from command line arguments.
Example: emp6.sh
#! /bin/sh
for pattern in “$@”; do #for pattern ; is also same
grep “$pattern” emp.lst || echo “Pattern $pattern not found”
done
106
basename: Changing Filename
Extensions
• Useful in changing the extension of group of filenames.
• basename extracts the “base” filename from an absolute pathname:
Example1:
$basename /home/user1/test.pl
Output:
test.pl
• When basename is used with two arguments it strips off the second argument from the first
Example2:
$basename test2.doc doc
Output: test2.
107
basename: Changing Filename
• Example3: Renaming filename extension from .txt to .doc
• The set statement assigns positional parameters $1, $2 and so on, to its arguments. This is used
for picking up individual fields from the output of a program.
Example 1:
$ set 9876 2345 6213
$
• This assigns the value 9876 to the positional parameters $1, 2345 to $2 and 6213 to $3. It also sets
the other parameters $# and $*. 108
set and shift
$echo “\$1 is $1, \$2 is $2, \$3 is $3, The $# arguments are $*”
• We can use command substitution to extract individual fields from the date output.
Example 2:
$ set `date`
$ echo $*
109
Shift: Shifting Arguments Left
• Shift transfers the contents of positional parameters to its immediate lower numbered one.
• This is done as many times as the statement is called. When called once, $2 becomes $1, $3
becomes S2 and so on.
Example 1:
$ echo “$@” # $@ and $* are same
Mon Oct 8 08:02:45 IST 2007
$ echo $1 $2 $3
Mon Oct 8
$shift
$echo $1 $2 $3
Oct 8 08:02:45
$shift 2 # Shifts 2 places
$echo $1 $2 $3
08:02:45 IST 2007
110
Shift: Shifting Arguments Left
Example 2: emp7.sh
#! /bin/sh
case $# in
0|1) echo “Usage: $0 file pattern(S)” ;exit ;;
*) fname=$1
shift
for pattern in “$@” ; do
grep “$pattern” $fname || echo “Pattern $pattern not found”
done;;
esac
• Output: $emp7.sh emp.lst
Insufficient number of arguments
$emp7.sh emp.lst Rakesh 1006 9877
9876 Rakesh Director Productions
1006 Rohit Director Sales
111
Pattern 9877 not found.
Set -- : Helps Command Substitution
• A problem is encountered when the output of the command begins with a - .
Example:
$set `ls –l chp1`
Output:
-rwxr-xr-x: bad option(s)
• Since the permissions string begins with a -, set interprets it as an option and finds it to be bad one.
• set creates another problem when its arguments evaluates to a null string.
• Consider command:
$set `grep PPP /etc/passwd` // null
112
Set -- : Helps Command Substitution
• If the string PPP can’t be located in the file, set will operate with no arguments and puzzle the user by
displaying all variables on the terminal(its default output).
• The solution to both of these problems lies in the use of –- (twohyphens) immediately after set:
$set -- `ls –l chp1`
$set -- `grep usr1 /etc/passwd`
• Set now understands that the arguments following – are not to be treated as options.
• Also suppress its default behavior if its argument evaluate to null string.
113
The Here Document (<<)
• The shell uses the << symbol to read data from the same file containing the script. This is
referred to as a here document, signifying that the data is here rather than in separate file.
Eg:
Your program for printing the invoices has been executed on `date`. Check the print queue
MARK
• The string (MARK) is delimiter. The shell treats every line following the command and delimited
by MARK as input to the command.
114
The Here Document (<<)
Using the Here Document with Interactive Programs:
Eg:
$ empl.sh << END
> director
> emp.lst
> END
Output:
Enter the pattern to be searched: Enter the file to be used: Searching for director from
file emp.lst
9876|jai sharma|director|production|12/03/50|7000
2365|barun sengupta|director|personnel|11/05/47|7800
115
trap command
trap: interrupting a Program
• The trap is used to do the things needed when the script receives signal
• Trap statement is normally placed at the beginning of a shell script and uses two lists:
• When a script is sent any of the signals in signal_list, trap executes the commands in
command_list.
• The signal list can contain the integer values or names (without SIG prefix), those used with kill
command.
116
trap command
Eg: To remove all temporary files named after the PID number of the shell:
trap ‘rm $$* ; echo “Program Interrupted” ; exit’ HUP INT TERM
• trap is a signal handler. Here, it first removes all files expanded from $$*, echoes a message and
finally terminates the script when the signals SIGHUP(1), SIGINT(2) or SIGTERM(15) are sent to
the shell process running the script.
117
trap command
Eg: To remove all temporary files named after the PID number of the shell:
trap ‘rm $$* ; echo “Program Interrupted” ; exit’ HUP INT TERM
rm $$*
rm is the command to remove files.
$$ is the process ID (PID) of the currently running shell.
$$* likely means that any file with the name starting with the process ID will be removed. This is
useful for cleaning up temporary files associated with this script's execution.
echo “Program Interrupted”: This command prints the message "Program Interrupted" to the
terminal.
exit: This command exits the script.
HUP: Signal 1, typically sent when a terminal is closed.
INT: Signal 2, typically sent when Ctrl+C is pressed.
TERM: Signal 15, the default signal sent by the kill command.
118
trap command
To ignore the signal and continue processing, make the script to ignore such signals by using a null
command list.
Eg: trap ‘ ’ 1 2 15
119
End of Module 4
120
Write a shell script to add two numbers
#!/bin/sh
121
Simple shell program to check if a given number is positive or negative
#!/bin/sh
echo "Enter a number:"
read number
if [ "$number" -gt 0 ]; then
echo "The number is positive."
elif [ "$number" -lt 0 ]; then
echo "The number is negative."
else
echo "The number is zero."
fi
122
Write a shell script to swap two numbers
#!/bin/sh
echo "Enter the first number:"
read num1
echo "Enter the second number:"
read num2
echo "Before swapping: num1 = $num1, num2 = $num2"
123
Write a shell script using if to perform all arithmetic operations
124