[go: up one dir, main page]

0% found this document useful (0 votes)
83 views24 pages

Unit 4 Notes

The document discusses shell scripting in Unix. It describes that shell scripts allow storing groups of commands in files to execute them regularly. Shell scripts run in a separate child shell process and use file extensions like .sh. The document then provides an example shell script and explains how to make it executable and run it. It also discusses using command line arguments, special parameters, and conditional execution using logical operators.

Uploaded by

Faza Ulfath
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
83 views24 pages

Unit 4 Notes

The document discusses shell scripting in Unix. It describes that shell scripts allow storing groups of commands in files to execute them regularly. Shell scripts run in a separate child shell process and use file extensions like .sh. The document then provides an example shell script and explains how to make it executable and run it. It also discusses using command line arguments, special parameters, and conditional execution using logical operators.

Uploaded by

Faza Ulfath
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

UNIX SHELL PROGRAMMING(21CS482)

Module - 4

Introduction to the Shell Scripting


Shell Scripts
When a group of commands have to be executed regularly, they should be stored in a file, and
the file itself executed as a shell script or shell program. Normally .sh extension is used for
shell scripts. This makes it easy to match them with wild-cards. Shell scripts are executed in a
separate child shell process, and this sub-shell need not be of the same type as user’s login shell.
Even if user’s login shell is Bourne, user can use a Korn sub-shell to run the script. By default,
the child and parent shells belong 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 user’s script.

Consider a shell script, script.sh

The script runs three echo commands and shows the use of variable evaluation and command
substitution. It also prints the calender of the current month.

script.sh
#!/bin/sh

# script.sh : Sample shell script

echo “Today’s date:`date`”

echo “This month’s calender:”

cal `date “+%m 20%y” `

echo “My shell:$SHELL”

The comment character (#) can be placed anywhere in a line. The shell ignores all the characters
placed on its right. The first line is interpreter line which begins with #! and is followed by the
pathname of the shell to be used for running the script. This line specifies the Bourne shell. To
run the script, make it executable first and then invoke the script name.

$ chmod +x script.sh

SDMIT, Ujire Page 1


UNIX SHELL PROGRAMMING(21CS482)

$ script.sh

Today’s date : Mon Jan 6 10:02:42 IST 2003

This month’s calender:

January 2003
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

My shell: /bin/sh

Shell scripts are executed by a child shell. The child shell reads and executes each statement (in
interpretive mode).

User can explicitly spawn a child of his choice with the script name as argument:

sh script.sh Will spawn a Bourne shell

read: Making Scripts Interactive

The read statement in the shell’s internal tool for taking input from user i.e making scripts
interactive. It is used with one or more variables. Input supplied through the standard input is
read into these variables. When user use a statement like

read name

The script pauses at that point to take input from keyboard. Whatever user entered is stored in the
variable name. Since this is a form of assignment, no $ is used before name. The script emp1.sh
uses read to take a search string and filename from the terminal. Shell scripts accept comments
prefixed by # anywhere in a line.

#!/bin/sh

# emp1.sh: Interactive version – uses read to take two inputs

SDMIT, Ujire Page 2


UNIX SHELL PROGRAMMING(21CS482)

echo “Enter the pattern to be searched: \c” # No newline

read pname

echo “Enter the file to be used: \c”

read filename

echo “Searching for $pname from file $filename”

grep “$pname” $filename

echo “Selected records shown above”

$ emp1.sh

Enter the pattern to be searched: director

Enter the file to be used: emp.lst

Searching for director for file emp.lst

9876| jai sharma | director | production |12/03/50 |7000

2365| barun sengupta | director | personnel |11/05/47 |7800

Selected records shown above

The script first asks for a pattern to be entered. Input the string director, which is assigned to the
variable pname. The script asks for the filename, enter the string emp.lst ,which is assigned to
the variable flname. grep then runs with these two variables as arguments.

A single read statement can be used with one or more variables to let you enter multiple
arguments.

read pname flname

SDMIT, Ujire Page 3


UNIX SHELL PROGRAMMING(21CS482)

If the number of arguments supplied is less than the number of variables accepting them, any
leftover variables will simply remain unassigned. When the number of arguments exceeds the
number of variables, the remaining words are assigned to the last variable.

Using Command Line Arguments


Shell scripts also accepts arguments from the command line. Shell scripts can run
noninteractively and be used with redirection and pipelines. When arguments are specified with a
shell script, they are assigned to certain special “variables” rather positional parameters. The
first argument is read by the shell into the parameter $1, the second argument into $2 and so on.
In additional to these positional parameters there are few other special parameters used by the
shell.

$* - It stores the complete set of positional paraneters as a single-string.

$# - It is set to the number of arguments specified. This lets user to design scripts that check
whether the right number of arguments have been entered.

$0 – Holds the command name itself. You can link a shell script to be invoked by more than one
name. The script logic can check $0 to behave differently depending on the name by which it is
invoked.

Table 1: Special Parameters Used by the Shell

Shell Parameter Significance

$1,$2 …. Positional parameters representing command line arguments

$# Number of arguments specified in command line

$0 Name of executed commad

$* Complete set of positional parameters as a single string

“$@” Each quoted string treated as a separate argument

SDMIT, Ujire Page 4


UNIX SHELL PROGRAMMING(21CS482)

$? Exit status of last command

$$ PID of the current shell

$! PID of the last background job

#!/bin/sh

# emp2.sh

echo “Program: $0

The number of arguments specified is $#

The arguments are $*”

grep “$1” $2

echo “\nJob Over”

emp2.sh

The script emp2.sh runs grep with two positional parameters that are set by the script arguments
director and emp.lst

$ emp2.sh director emp.lst

Program: emp2.sh

The number of arguments specified is 2

The arguments are director emp.lst

1006 | chanchal singhvi | director | sales |03/09/38 |6700

6521 | lalit chowdury | director | marketing | 26/09/45 | 8200

Job Over

When arguments are specified in this way, the first word(the command itself) is assigned to $0.
The second word (the first argument) to $1. The third word (the second argument) to $2. User

SDMIT, Ujire Page 5


UNIX SHELL PROGRAMMING(21CS482)

can use positional parameters up to $9. When user use a multiword string to represent a single
command line argument, he must quote it. To look for chanchal singhvi, use emp2.sh “chanchal
singhvi “ emp.lst All assignments to positional and special parameters are made by the shell.

exit and EXIT Status of Command


Shell scripts uses same command as C program to terminate a program. It has the name exit in
shell and exit() in C. The command is generally run with a numeric argument.

• exit 0 Used when everything went fine


• exit 1 Used when something when wrong

There are two very common exit values. User don’t need to place exit statement at the end of
every shell script because the shell understands when script execution is complete. It’s through
the exit command or function that every command returns an exit status to the caller. A
command is said to return a true exit status if it executes successfully and false if it fails.

The cat command as used below:

$ cat foo

cat : can’t open foo

Returns a nonzero exit status because it couldn’t open the file.

The shell offers a variable ($?) and a command (test) that evaluates a command’s exit status.

The Parameter $?
The paameter $? stores the exit status of the last command. It has the value 0 if the command
succeds and a nonzero value if it fails. This parameter is set by exit’s argument. If no exit status
is specified, then $? is set to zero (true).

$ grep director emp.lst >/dev/null; echo $?

0 Success

$ grep manager emp.lst >/dev/null; echo $?

1 Failure-in finding pattern

SDMIT, Ujire Page 6


UNIX SHELL PROGRAMMING(21CS482)

$ grep manager emp3.lst >/dev/null; echo $?

grep: can’t open emp3.lst Failure in opening file

The exit status is extremely important for programmers. They use it to devise program logic that
branches into different paths depending on the success or failure of a command.

The Logical Operators && and || - Conditional Execution


The shell provides two operators that allow conditional execution.

1. &&

2. ||

The syntax is as follows:

1. cmd1 && cmd2

2. cmd1 || cmd2

The && delimits two commands. The command cmd2 is executed only when cmd1 succeeds.
&& operator can be used along with grep as follows:

$ grep ‘director’ emp.lst && echo “pattern found in file”

1006 | chanchal singhvi | director |sales |03/09/38 | 6700

6521 | lalit chowdury | director |marketing |26/09/45 | 8200

pattern found in file

The || operator plays an inverse role. The second command is executed only when the first fails.
If you “grep” a pattern from a file without success, you can notify the failure:

$ grep ‘manager’ emp.lst || echo “Pattern not found”

Pattern not found

grep “$1” $2 || exit 2

echo “Pattern found-Job Over”

The && and || operators are recommended for making simple decisions.

SDMIT, Ujire Page 7


UNIX SHELL PROGRAMMING(21CS482)

The if Conditional
The if statement makes two-way decisions depending on the fulfillment of a certain condition. In
the shell, the statement uses the following forms:

if command is successful

then

execute commands

else

execute commands

fi

Form 1

if command is successful

then

execute commands

fi

Form 2

if command is successful

then

execute commands

elif command is successful

then …

else ….

fi

Form 3

if also requires a then. It evaluates the success or failure of the command that is specified in it’s
command line. If command succeeds, the sequence of commands following it is executed. If

SDMIT, Ujire Page 8


UNIX SHELL PROGRAMMING(21CS482)

command fails, then the else statement (if present) is executed. Ever if is closed with a
corresponding fi.

#!/bin/sh

# emp3.sh : Using if and else

# if grep “^$1” /etc/passwd 2>/dev/null

then

echo “Pattern found – Job Over”

else

echo “Pattern not found”

fi

emp3.sh

In the script emp3.sh, grep is first executed and simple if-else construct tests the exit status of
grep.

$ emp3.sh ftp

ftp:*:325:15:FTP Users:/users1/home/ftp:/bin/true

Pattern found – Job Over

$ emp3.sh mail

Pattern not found

SDMIT, Ujire Page 9


UNIX SHELL PROGRAMMING(21CS482)

The case Conditional


The case statement matches an expression for more than one alternative and uses a compact
construct to permit multiway branching. case also handles string tests, in a more efficient manner
than if.

The general syntax of the case statement is as follows:

case expression in

pattern1) commands1 ;;

pattern2) commands2 ;;

pattern3) commands3 ;;

…………

esac

case first matches expression with pattern1. If the match succeeds, then it executes commands1,
which may be one or more commands. If the match fails, then pattern2 is matched and so forth.
Each command list is terminated with a pair of semicolons, and the entire construct is closed
with esac (reverse of case)

Consider a simple script menu.sh that uses case. The script accepts values from 1 to 5 and
performs some action depending on the number keyed in. The five menu choices are displayed
with a multi-line echo statement:

case matches the value of $choice with the strings 1,2,3,4 and 5. If the user enters a 1, the ls –l
command is executed. Option 5 quits the program. The last option (*) matches any option not
matched by the previous options.

#!/bin/sh

# menu.sh

echo “ MENU\n”

SDMIT, Ujire Page 10


UNIX SHELL PROGRAMMING(21CS482)

1.List of files\n2. Processes of user\n3. Today’s Date

4.Users of system\n5. Quit to UNIX\nEnter your option: \c”

read choice

case “$choice” in

1) ls –l ;;
2) ps –f ;;
3) date ;;
4) who ;;
5) exit ;;

*) echo “Invalid option”

esac

menu.sh

User can see today’s date by choosing the third option:

$ menu.sh

MENU

1.List of files

2.Processes of user

3.Today’s date

4.Users of system

5.Quit to UNIX

Enter your option : 3

Tue Jan 7 18:03:06 IST 2003

SDMIT, Ujire Page 11


UNIX SHELL PROGRAMMING(21CS482)

expr
expr command combines two functions in one:

1. Performs arithmetic operations on integers

2. Manipulate strings

expr is used for performing both above functions.

Computation

expr can perform the four basic aithmetic operations as well as the modulus(remainder) function.

$ x=3 y=5

$ expr 3+5

$ expr $x - $y

-2

$ expr 3 \* 5

15

$ expr $y / $x

$ expr 13 % 5

The operand such as +,-,*,etc must be enclosed on either side by whitespace. The multiplication
operand(*) has to be escaped to prevent shell from interpreting it as the filename metacharacter.
Since, expr can handle only integers, division yields only the integral part. expr is often used
with the command substitution to assign a variable. For example, user can set a variable z to the
sum of two numbers:

$ x=6 y=2 ; z=`expr $x + $y`

$ echo $z

SDMIT, Ujire Page 12


UNIX SHELL PROGRAMMING(21CS482)

expr is also used for incrementing the value of a variable.

$ x=5

$ x=`expr $x + 1`

$ echo $x

String Handling

expr can perform three important string functions:

1. Determine the length of the string

2. Extract a substring

3. Locate the position of a character in a string

The length of a String : The regular expression .* signifies to expr that it has to print the number
of characters matching the pattern. i.e the length of the entire string.

$ expr “abcdefghijkl” : ‘.*’

12

In above example, expr has counted the number of occurrences of any character (.*) This feature
is useful in validating data entry.

Extracting a Substring – expr can extract a string enclosed by the escaped characters \ (and \) . If
user wish to extract the 2-digit year from a 4-digit string, then he must create a pattern group and
extract it in following way:

$ stg=2003

$ expr “$stg” : ‘..\ (..\)’ Extracts last two characters

03

SDMIT, Ujire Page 13


UNIX SHELL PROGRAMMING(21CS482)

Locating Position of a Character – expr also return the location of the first occurrence of a
character inside a string. To locate the position of the character d in the string value of $stg, user
has to count the number of characters which are not d ([^d]*), followed by a d:

$ stg=abcdefgh ; expr “$stg” : ‘[^d]*d’

while Looping
The while statement repeatedly performs a set of instructions until the control command returns a
true exit status. The general syntax of this command is as follows:

while condition is true

do

commands

done

The commands enclosed by do and done are executed repeatedly as long as condition remains
true.

Using while to Wait for a File

There are situations when a program needs to read a file that is created by another program, but it
also has to wait until the file is created. The script, monitfile.sh periodically monitors the disk
for existence of the file and then executes the program once the file has been located. It makes
use of the external sleep command that makes the script pause for the duration(in seconds) as
specified in the argument. The loop executes repeatedly as long as the file invoice.lst can’t b
read.If the file becomes readable, the loop is terminated and the program alloc.pl is executed.

#!/bin/sh

# monitfile.sh

SDMIT, Ujire Page 14


UNIX SHELL PROGRAMMING(21CS482)

while [ ! -r invoice.lst]

do

sleep 60

done

alloc.pl

monitfile.sh

for: Looping with a List


The shell’s for loop differs in structure from the ones used in other programming languages.
There is no three-part structure as used in C,awk and perl. Unlike while and until for doesn’t test
a condition, but uses a list instead.

for variable in list

do

commands

done

The loop body also uses the keywords do and done, but the additional parameters here are
variable and list.Each whitespace-separated word in list is assigned to variable in turn and
commands are executed until list is exhausted.

Example:

$ for file in chap20 chap21 chap22 chap23 ; do

> cp $file ${file}.bak

> echo $file copied to $file.bak

> done

chap20 copied to chap20.bak

SDMIT, Ujire Page 15


UNIX SHELL PROGRAMMING(21CS482)

chap21 copied to chap21.bak

chap22 copied to chap22.bak

chap23 copied to chap23.bak

The list here comprises a series of character strings (chap20 and onwards, representing
filenames) separated by whitespace. Each item in the list is assigned to the variable file. file first
gets the value chap20, then chap21, and so on. Each file is copied with a .bak extension and the
completion message displayed after every file is copied.

The HERE DOCUMENT (<<)


There are occasions when the data your program reads is fixed and fairly limited. The shell uses
<< symbols 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 a separate file.Any command using
standard input can also take input from a here document.

This feature is useful when used with commands that don’t accept filename as arguments (like
mailx command). If the message is short, you can have both the command and message in the
same script.

mailx sharma << MARK

Your program for printing the invoices has been executed

on ‘date’. Check the print queue

The updated file is known as $flname

MARK

The here document symbol (<<) is followed by three lines of data and a delimiter (the string
MARK). The shell treats every line following the command and delimited by MARK as input to
the command. sharma at the other end will see the three lines of message text with the date
inserted by command substitution and the evaluated filename.

Using the Here Document with Interactive Programs

SDMIT, Ujire Page 16


UNIX SHELL PROGRAMMING(21CS482)

Many commands require input from the user. It is the same input that is keyed in, in response to
a series of questions posed by the command. For instance, user may have to enter a y two or
three times when the command pauses, but the questions may not come in quick succession.
Rather than wait for the prompt, we can instruct the script to take input from a here document.

We can make the script work noninteractively by supplying the inputs through a here document:

$ emp1.sh << END

> director

> emp.lst

> END

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/02/50 | 7000

2365 | barun sengupta | director | personnel | 11/05/47 | 7800

set

The set command is used for extracting fields from output. set assigns its arguments to the
positional parameters $1,$2 and so on. This feature is especially useful for picking up individual
fields from output of a program. set is used to convert its arguments to positional parameters.

$ set 9876 2345 6213

$_

This assigns the value 9876 to the positional parameter $1, 2345 to $2 and 6213 to $3. It also
sets the other parameters $# and $*. User can verify this by echoing each parameter in turn:

$ echo “\$1 is $1, \$2 is $2, \$3 is $3”

$1 is 9876, $2 is 2345, $3 is 6213

SDMIT, Ujire Page 17


UNIX SHELL PROGRAMMING(21CS482)

$ echo “The $# arguments are $*”

The 3 arguments are 9876 2345 6213

Command substitution can be used to extract individual fields from the date output as follows:

$ set `date`

$ echo $*

Wed Jan 8 09:40:35 IST 2003

$ echo “The date today is $2 $3, $6”

The date today is Jan 8,2003

trap : Interrupting a Program


By default, shell script terminates whenever the interrupt key is pressed. The trap statement lets
you do the things you want in case the script receives a signal. The statement is normally placed
at the beginning of a shell script and uses two lists:

trap ‘command_list’ signal_list

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 of one or more signals.

If you habitually create temporary files named after the PID number of the shell, you should use
the services of trap to remove them whenever an interrupt occurs.

trap ‘rm $$* ; echo “Program interrupted” ; exit’ HUP INT TERM

trap is a signal handler. It first removes all files expanded from $$*, echoes a message and
finally terminates the script when the signals SIGUP(1),SIGINT(2) or SIGTERM(15) are sent to
the shell process running the script. When the interrupt key is pressed, it sends the signal number
2.

SDMIT, Ujire Page 18


UNIX SHELL PROGRAMMING(21CS482)

Sample Validation and Data Entry Scripts


valcode.sh : Script to Look Up a Code List

The script valcode.sh uses the set and shift features to accept and validate a department code. It
looks up a code list maintained as a here document in the script file itself, and flashes the
department name on the terminal. Since echo always produces a true exi status, the statement
issuing the prompt is itself used as the control command of the while loop. The pattern selected
by grep is split by set on the | into three positional parameters. This is done by changing the IFS
setting that normally consists of whitespace. shift 3 flushes the positional parameters before
starting the next iteration.

#!/bin/sh

# valcode.sh : Uses a here document to look up a code list

IFS=”|” # Reset field separator to pipe

while echo “Enter department code :\c” ; do

read dcode

set -- `grep “^dcode” <<limit

01|accounts|6213

02|admin|5423

03|marketing|6521

04|personnel|2365

05|production|9876

06|sales|1006

limit ` Closing ` mark end of standard input

SDMIT, Ujire Page 19


UNIX SHELL PROGRAMMING(21CS482)

case $# im

3) echo “Department name : $2\nEmp-id of head of dept : $3\n”

shift 3;; # Flush out the positional parameters

*) echo “Invalid code” ; continue

esac

done

valocde.sh

$ valcode.sh

Enter department code : 99

Invalid code

Enter department code : 02

Department name : admin

Emp-id of head of dept : 5423

Enter department code : 04

Department name : personnel

Emp-id of head of dept : 2365

Enter department code : [Ctrl-c]

The script doesn’t terminate normally, but user can use the interrupt key at any time to abort the
program.

SDMIT, Ujire Page 20


UNIX SHELL PROGRAMMING(21CS482)

dentry1.sh : A Data Entry Script

dentry1.sh accepts a designation code and its description from the terminal, performs some
rudimentary validation checks, and then adds an entry to a file (design.lst). It validates the code
entered with the ones that already exist in the file. The script repeatedly prompts the user until
the right response is obtained.

The script prompts for two fields,the designation code and description, and uses two while loops,
one enclosed by the other. The code has to be reentered if it exists in the file or if it doesn’t have
a two-digit structure. Similarly the description has to be reentered if it contains a nonaplhabettic
character other than a space (*[!\ a-zA-Z]*). The continue statement lets user to reenter the data
or start a fresh cycle. The break statement in the inner loop quits the loop after ending the line.

The entries in the file design.lst is as follows:

$ cat design.lst

01| accounts

02| admin

03| marketing

04| personnel

05| production

06| sales

$ dentry1.sh

Designation code: 01

Code exists

Designation code:07

Description :security officer

SDMIT, Ujire Page 21


UNIX SHELL PROGRAMMING(21CS482)

Wish to continue? (y/n) : Y

Designation code: 8

Invalid code

Designation code: 08

Description :vice president 1

Can contain only alphabets and spaces

Description :vice president

Wish to continue? (y/n) : n

Normal exit

#!/bin/sh

# dentry1.sh

trap ‘echo Not to be interrupted’ INT # [Ctrl-c] won’t work

trap ‘echo Signal received ; exit’ HUP TERM # but these two signals will

file=design.lst

while echo “Designation code: \c” >/dev/tty ; do

read design

case “$desig” in # First check if the code exists

[0-9][0-9] if grep “^$desig” $file >dev/null ; then

echo “Code exists”

SDMIT, Ujire Page 22


UNIX SHELL PROGRAMMING(21CS482)

continue; # Go to loop beginning

fi ;;

*) echo “Invalid code”

continue ;;

esac

while echo “Description : \c” >/dev/tty ; do

read desc

case “$desc” in

*[!\ a-zA-Z]*) echo “Can contain only alphabets and spaces” >/dev/tty

continue;; # Go to inner loop beginning

“ “) echo “Description not entered” >/dev/tty

continue;;

*) echo “$desig|$desc”

break # Terminate this inner loop

esac

done >> file # Appends to same file that is looked up

echo “\nWish to continue? (y/n) : \c”

read answer

case “$answer” in

[yY*] continue;; # Go to outer loop beginning

*) break;; # Terminate outer loop

SDMIT, Ujire Page 23


UNIX SHELL PROGRAMMING(21CS482)

esac

done

echo “Normal exit”

dentry1.sh

SDMIT, Ujire Page 24

You might also like