0% found this document useful (0 votes)
26 views98 pages

Unit 3

Uploaded by

patelpreet8686
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)
26 views98 pages

Unit 3

Uploaded by

patelpreet8686
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/ 98

Unit-3:Shell Programming

3.1 Screen Editor “vi”


We will understand how the vi Editor works in Unix. There are many ways to edit
files in Unix. Editing files using the screen-oriented text editor vi is one of the
best ways. This editor enables you to edit lines in context with other lines in the
file.
An improved version of the vi editor which is called the VIM has also been made
available now. Here, VIM stands for Vi Improved.
vi is generally considered the de facto standard in Unix editors because −
 It's usually available on all the flavors of Unix system.
 Its implementations are very similar across the board.
 It requires very few resources.
 It is more user-friendly than other editors such as the ed or the ex.
You can use the vi editor to edit an existing file or to create a new file from
scratch. You can also use this editor to just read a text file.

Starting the vi Editor

The following table lists out the basic commands to use the vi editor −

Sr.No. Command & Description

1 vi filename
Creates a new file if it already does not exist, otherwise opens an existing file.

2 vi -R filename
Opens an existing file in the read-only mode.

3 view filename
Opens an existing file in the read-only mode.

1
Unit-3:Shell Programming

Following is an example to create a new file testfile if it already does not exist in
the current working directory −
$vi testfile
The above command will generate the following output −
|
~
~
~
~
~
~
~
~
~
~
~
~
"testfile" [New File]
You will notice a tilde (~) on each line following the cursor. A tilde represents an
unused line. If a line does not begin with a tilde and appears to be blank, there is a
space, tab, newline, or some other non-viewable character present.
You now have one open file to start working on. Before proceeding further, let us
understand a few important concepts.

Operation Modes

While working with the vi editor, we usually come across the following two
modes −
 Command mode − This mode enables you to perform administrative tasks
such as saving the files, executing the commands, moving the cursor,
cutting (yanking) and pasting the lines or words, as well as finding and
replacing. In this mode, whatever you type is interpreted as a command.
 Insert mode − This mode enables you to insert text into the file. Everything
that's typed in this mode is interpreted as input and placed in the file.
vi always starts in the command mode. To enter text, you must be in the insert
mode for which simply type i. To come out of the insert mode, press the Esc key,
which will take you back to the command mode.
2
Unit-3:Shell Programming

Hint − If you are not sure which mode you are in, press the Esc key twice; this
will take you to the command mode. You open a file using the vi editor. Start by
typing some characters and then come to the command mode to understand the
difference.

Getting Out of vi

The command to quit out of vi is: q. once in the command mode, type colon, and
'q', followed by return. If your file has been modified in any way, the editor will
warn you of this, and not let you quit. To ignore this message, the command to
quit out of vi without saving is :q!. This lets you exit vi without saving any of the
changes.
The command to save the contents of the editor is :w. You can combine the above
command with the quit command, or use :wq and return.
The easiest way to save your changes and exit vi is with the ZZ command. When
you are in the command mode, type ZZ. The ZZcommand works the same way as
the :wq command.
If you want to specify/state any particular name for the file, you can do so by
specifying it after the :w. For example, if you wanted to save the file you were
working on as another filename called filename2, you would type :w
filename2 and return.

Moving within a File

To move around within a file without affecting your text, you must be in the
command mode (press Esc twice). The following table lists out a few commands
you can use to move around one character at a time −

Sr.No. Command & Description

1 k
Moves the cursor up one line

2 j
Moves the cursor down one line

3
Unit-3:Shell Programming

3 h
Moves the cursor to the left one character position

4 l
Moves the cursor to the right one character position

The following points need to be considered to move within a file −


 vi is case-sensitive. You need to pay attention to capitalization when using
the commands.
 Most commands in vi can be prefaced by the number of times you want the
action to occur. For example, 2j moves the cursor two lines down the cursor
location.
There are many other ways to move within a file in vi. Remember that you must
be in the command mode (press Esc twice). The following table lists out a few
commands to move around the file −
Given below is the list of commands to move around the file.
Sr.No. Command & Description

1 0 or |
Positions the cursor at the beginning of a line

2 $
Positions the cursor at the end of a line

3 w
Positions the cursor to the next word

4 b
Positions the cursor to the previous word

4
Unit-3:Shell Programming

5 (
Positions the cursor to the beginning of the current sentence

6 )
Positions the cursor to the beginning of the next sentence

7 E
Moves to the end of the blank delimited word

8 {
Moves a paragraph back

9 }
Moves a paragraph forward

10 [[
Moves a section back

11 ]]
Moves a section forward

12 n|
Moves to the column n in the current line

13 1G
Moves to the first line of the file

14 G

5
Unit-3:Shell Programming

Moves to the last line of the file

15 nG
Moves to the nth line of the file

16 :n
Moves to the nth line of the file

17 fc
Moves forward to c

18 Fc
Moves back to c

19 H
Moves to the top of the screen

20 nH
Moves to the nth line from the top of the screen

21 M
Moves to the middle of the screen

22 L
Move to the bottom of the screen

23 nL
Moves to the nth line from the bottom of the screen

6
Unit-3:Shell Programming

24 :x
Colon followed by a number would position the cursor on the line number represente

Control Commands

The following commands can be used with the Control Key to performs functions
as given in the table below −
Given below is the list of control commands.
Sr.No. Command & Description

1 CTRL+d
Moves forward 1/2 screen

2 CTRL+f
Moves forward one full screen

3 CTRL+u
Moves backward 1/2 screen

4 CTRL+b
Moves backward one full screen

5 CTRL+e
Moves the screen up one line

6 CTRL+y
Moves the screen down one line

7 CTRL+u

7
Unit-3:Shell Programming

Moves the screen up 1/2 page

8 CTRL+d
Moves the screen down 1/2 page

9 CTRL+b
Moves the screen up one page

10 CTRL+f
Moves the screen down one page

11 CTRL+I
Redraws the screen

Editing Files

To edit the file, you need to be in the insert mode. There are many ways to enter
the insert mode from the command mode −

Sr.No. Command & Description

1 i
Inserts text before the current cursor location

2 I
Inserts text at the beginning of the current line

3 a
Inserts text after the current cursor location

8
Unit-3:Shell Programming

4 A
Inserts text at the end of the current line

5 o
Creates a new line for text entry below the cursor location

6 O
Creates a new line for text entry above the cursor location

Deleting Characters

Here is a list of important commands, which can be used to delete characters and
lines in an open file −

Sr.No. Command & Description

1 x
Deletes the character under the cursor location

2 X
Deletes the character before the cursor location

3 dw
Deletes from the current cursor location to the next word

4 d^
Deletes from the current cursor position to the beginning of the line

5 d$

9
Unit-3:Shell Programming

Deletes from the current cursor position to the end of the line

6 D
Deletes from the cursor position to the end of the current line

7 dd
Deletes the line the cursor is on

As mentioned above, most commands in vi can be prefaced by the number of


times you want the action to occur. For example, 2xdeletes two characters under
the cursor location and 2dd deletes two lines the cursor is on.
It is recommended that the commands are practiced before we proceed further.

Change Commands

You also have the capability to change characters, words, or lines in vi without
deleting them. Here are the relevant commands −

Sr.No. Command & Description

1 cc
Removes the contents of the line, leaving you in insert mode.

2 cw
Changes the word the cursor is on from the cursor to the lowercase w end of the word.

3 r
Replaces the character under the cursor. vi returns to the command mode after the repla

4 R
Overwrites multiple characters beginning with the character currently under the cursor

10
Unit-3:Shell Programming

the overwriting.

5 s
Replaces the current character with the character you type. Afterward, you are left in th

6 S
Deletes the line the cursor is on and replaces it with the new text. After the new text i
insert mode.

Copy and Paste Commands

You can copy lines or words from one place and then you can paste them at
another place using the following commands −

Sr.No. Command & Description

1 yy
Copies the current line.

2 yw
Copies the current word from the character the lowercase w cursor is on, until the end

3 p
Puts the copied text after the cursor.

4 P
Puts the yanked text before the cursor.

Advanced Commands

11
Unit-3:Shell Programming

There are some advanced commands that simplify day-to-day editing and allow
for more efficient use of vi −
Given below is the list advanced commands.
Sr.No. Command & Description

1 J
Joins the current line with the next one. A count of j commands join many lines.

2 <<
Shifts the current line to the left by one shift width.

3 >>
Shifts the current line to the right by one shift width.

4 ~
Switches the case of the character under the cursor.

5 ^G
Press Ctrl and G keys at the same time to show the current filename and the status.

6 U
Restores the current line to the state it was in before the cursor entered the line.

7 u
This helps undo the last change that was done in the file. Typing 'u' again will re-do th

8 J
Joins the current line with the next one. A count joins that many lines.

12
Unit-3:Shell Programming

9 :f
Displays the current position in the file in % and the file name, the total number of file

10 :f filename
Renames the current file to filename.

11 :w filename
Writes to file filename.

12 :e filename
Opens another file with filename.

13 :cd dirname
Changes the current working directory to dirname.

14 :e #
Toggles between two open files.

15 :n
In case you open multiple files using vi, use :n to go to the next file in the series.

16 :p
In case you open multiple files using vi, use :p to go to the previous file in the series.

17 :N
In case you open multiple files using vi, use :N to go to the previous file in the series.

18 :r file

13
Unit-3:Shell Programming

Reads file and inserts it after the current line.

19 :nr file
Reads file and inserts it after the line n.

Word and Character Searching

The vi editor has two kinds of searches: string and character. For a string search,
the / and ? commands are used. When you start these commands, the command
just typed will be shown on the last line of the screen, where you type the
particular string to look for.
These two commands differ only in the direction where the search takes place −
 The / command searches forwards (downwards) in the file.
 The ? command searches backwards (upwards) in the file.
The n and N commands repeat the previous search command in the same or the
opposite direction, respectively. Some characters have special meanings. These
characters must be preceded by a backslash (\) to be included as part of the search
expression.

Sr.No. Character &Description

1 ^
Searches at the beginning of the line
(Use at the beginning of a search expression).

2 .
Matches a single character.

3 *
Matches zero or more of the previous character.

14
Unit-3:Shell Programming

4 $
End of the line (Use at the end of the search expression).

5 [
Starts a set of matching or non-matching expressions.

6 <
This is put in an expression escaped with the backslash
to find the ending or the beginning of a word.

7 >
This helps see the '<' character description above.

The character search searches within one line to find a character entered after the
command. The f and F commands search for a character on the current line
only. f searches forwards and F searches backwards and the cursor moves to the
position of the found character.
The t and T commands search for a character on the current line only, but for t,
the cursor moves to the position before the character, and T searches the line
backwards to the position after the character.

Set Commands

You can change the look and feel of your vi screen using the following:
set commands. Once you are in the command mode, type: set followed by any of
the following commands.

Sr.No. Command & Description

1 :set ic
Ignores the case when searching

15
Unit-3:Shell Programming

2 :set ai
Sets autoindent

3 :set noai
Unsets autoindent

4 :set nu
Displays lines with line numbers on the left side

5 :set sw
Sets the width of a software tabstop. For example, you would set
a shift width of 4 with this command — :set sw = 4

6 :set ws
If wrapscan is set, and the word is not found at the bottom of the file, it will try searchi

7 :set wm
If this option has a value greater than zero, the editor will automatically "word wrap".
For example, to set the wrap margin to two characters,
you would type this: :set wm = 2

8 :set ro
Changes file type to "read only"

9 :set term
Prints terminal type

10 :set bf

16
Unit-3:Shell Programming

Discards control characters from input

Running Commands

The vi has the capability to run commands from within the editor. To run a
command, you only need to go to the command mode and type :! command.
For example, if you want to check whether a file exists before you try to save your
file with that filename, you can type :! ls and you will see the output of ls on the
screen.
You can press any key (or the command's escape sequence) to return to your vi
session.

Replacing Text

The substitution command (:s/) enables you to quickly replace words or groups of
words within your files. Following is the syntax to replace text −
:s/search/replace/g
The g stands for globally. The result of this command is that all occurrences on
the cursor's line are changed.

Important Points to Note

The following points will add to your success with vi −


 You must be in command mode to use the commands. (Press Esc twice at
any time to ensure that you are in command mode.)
 You must be careful with the commands. These are case-sensitive.
 You must be in insert mode to enter text.
3.2Environmental & user defined variables
we will discuss in detail about the Unix environment. An important Unix concept
is the environment, which is defined by environment variables. Some are set by
the system, others by you, yet others by the shell, or any program that loads
another program.
A variable is a character string to which we assign a value. The value assigned
could be a number, text, filename, device, or any other type of data.

17
Unit-3:Shell Programming

For example, first we set a variable TEST and then we access its value using
the echo command −
$TEST="Unix Programming"
$echo $TEST
It produces the following result.
Unix Programming
Note that the environment variables are set without using the $ sign but while
accessing them we use the $ sign as prefix. These variables retain their values
until we come out of the shell.
When you log in to the system, the shell undergoes a phase called initialization to
set up the environment. This is usually a two-step process that involves the shell
reading the following files −

 /etc/profile
 profile
The process is as follows −
 The shell checks to see whether the file /etc/profile exists.
 If it exists, the shell reads it. Otherwise, this file is skipped. No error
message is displayed.
 The shell checks to see whether the file .profile exists in your home
directory. Your home directory is the directory that you start out in after
you log in.
 If it exists, the shell reads it; otherwise, the shell skips it. No error message
is displayed.
As soon as both of these files have been read, the shell displays a prompt −
$
This is the prompt where you can enter commands in order to have them executed.
Note − The shell initialization process detailed here applies to all Bourne type
shells, but some additional files are used by bash and ksh.

The .profile File

18
Unit-3:Shell Programming

The file /etc/profile is maintained by the system administrator of your Unix


machine and contains shell initialization information required by all users on a
system.
The file .profile is under your control. You can add as much shell customization
information as you want to this file. The minimum set of information that you
need to configure includes −

 The type of terminal you are using.


 A list of directories in which to locate the commands.
 A list of variables affecting the look and feel of your terminal.
You can check your .profile available in your home directory. Open it using the vi
editor and check all the variables set for your environment.

Setting the Terminal Type

Usually, the type of terminal you are using is automatically configured by either
the login or getty programs. Sometimes, the auto configuration process guesses
your terminal incorrectly.
If your terminal is set incorrectly, the output of the commands might look strange,
or you might not be able to interact with the shell properly.
To make sure that this is not the case, most users set their terminal to the lowest
common denominator in the following way −
$TERM=vt100
$

Setting the PATH

When you type any command on the command prompt, the shell has to locate the
command before it can be executed.
The PATH variable specifies the locations in which the shell should look for
commands. Usually the Path variable is set as follows −
$PATH=/bin:/usr/bin
$
Here, each of the individual entries separated by the colon character (:) are
directories. If you request the shell to execute a command and it cannot find it in
any of the directories given in the PATH variable, a message similar to the
following appears −
19
Unit-3:Shell Programming

$hello
hello: not found
$
There are variables like PS1 and PS2 which are discussed in the next section.

PS1 and PS2 Variables

The characters that the shell displays as your command prompt are stored in the
variable PS1. You can change this variable to be anything you want. As soon as
you change it, it'll be used by the shell from that point on.
For example, if you issued the command −
$PS1='=>'
=>
=>
=>
Your prompt will become =>. To set the value of PS1 so that it shows the
working directory, issue the command −
=>PS1="[\u@\h \w]\$"
The result of this command is that the prompt displays the user's username, the
machine's name (hostname), and the working directory.
There are quite a few escape sequences that can be used as value arguments for
PS1; try to limit yourself to the most critical so that the prompt does not
overwhelm you with information.

Sr.No. Escape Sequence & Description

1 \t
Current time, expressed as HH:MM:SS

2 \d
Current date, expressed as Weekday Month Date

3 \n

20
Unit-3:Shell Programming

Newline

4 \s
Current shell environment

5 \W
Working directory

6 \w
Full path of the working directory

7 \u
Current user’s username

8 \h
Hostname of the current machine

9 \#
Command number of the current command. Increases when a new command is entered

10 \$
If the effective UID is 0 (that is, if you are logged in as root), end the prompt with the
the $ sign

$ echo "this is a
> test"
this is a
test
$

21
Unit-3:Shell Programming

The example given below re-defines PS2 with a customized prompt −


$ PS2="secondary prompt->"
$ echo "this is a
secondary prompt->test"
this is a
test
$

3.2 Environmental & user defined variables

Environment Variables

Following is the partial list of important environment variables. These variables


are set and accessed as mentioned below −

Sr.No. Variable & Description

1 DISPLAY
Contains the identifier for the display that X11 programs should use by default.

2 HOME
Indicates the home directory of the current user: the default argument for the cd built-in

3 IFS
Indicates the Internal Field Separator that is used by the parser for word splitting afte

4 LANG
LANG expands to the default system locale; LC_ALL can be used to override this
is pt_BR, then the language is set to (Brazilian) Portuguese and the locale to Brazil.

5 LD_LIBRARY_PATH
A Unix system with a dynamic linker, contains a colonseparated list of directories that
search for shared objects when building a process image after exec, before searching in

22
Unit-3:Shell Programming

6 PATH
Indicates the search path for commands. It is a colon-separated list of directories in
commands.

7 PWD
Indicates the current working directory as set by the cd command.

8 RANDOM
Generates a random integer between 0 and 32,767 each time it is referenced.

9 SHLVL
Increments by one each time an instance of bash is started. This variable is useful fo
built-in exit command ends the current session.

10 TERM
Refers to the display type.

11 TZ
Refers to Time zone. It can take values like GMT, AST, etc.

12 UID
Expands to the numeric user ID of the current user, initialized at the shell startup.

Following is the sample example showing few environment variables −


$ echo $HOME
/root
$ echo $DISPLAY

$ echo $TERM
xterm
$ echo $PATH

23
Unit-3:Shell Programming

/usr/local/bin:/bin:/usr/bin:/home/amrood/bin:/usr/local/bin

Local variabels
we will learn how to use Shell variables in Unix. A variable is a character string to
which we assign a value. The value assigned could be a number, text, filename,
device, or any other type of data.
A variable is nothing more than a pointer to the actual data. The shell enables you
to create, assign, and delete variables.

Variable Names

The name of a variable can contain only letters (a to z or A to Z), numbers ( 0 to


9) or the underscore character ( _).
By convention, Unix shell variables will have their names in UPPERCASE.
The following examples are valid variable names −
_ALI
TOKEN_A
VAR_1
VAR_2
Following are the examples of invalid variable names −
2_VAR
-VARIABLE
VAR1-VAR2
VAR_A!
The reason you cannot use other characters such as !, *, or - is that these
characters have a special meaning for the shell.

Defining Variables

Variables are defined as follows −


variable_name=variable_value
For example −
NAME="Zara Ali"

24
Unit-3:Shell Programming

The above example defines the variable NAME and assigns the value "Zara Ali"
to it. Variables of this type are called scalar variables. A scalar variable can hold
only one value at a time.
Shell enables you to store any value you want in a variable. For example −
VAR1="Zara Ali"
VAR2=100

Accessing Values

To access the value stored in a variable, prefix its name with the dollar sign ($) −
For example, the following script will access the value of defined variable NAME
and print it on STDOUT −

#!/bin/sh

NAME="Zara Ali"
echo $NAME
The above script will produce the following value −
Zara Ali

Read-only Variables

Shell provides a way to mark variables as read-only by using the read-only


command. After a variable is marked read-only, its value cannot be changed.
For example, the following script generates an error while trying to change the
value of NAME −
#!/bin/sh

NAME="Zara Ali"
readonly NAME
NAME="Qadiri"
The above script will generate the following result −
/bin/sh: NAME: This variable is read only.

25
Unit-3:Shell Programming

Unsetting Variables

Unsetting or deleting a variable directs the shell to remove the variable from the
list of variables that it tracks. Once you unset a variable, you cannot access the
stored value in the variable.
Following is the syntax to unset a defined variable using the unset command −
unset variable_name
The above command unsets the value of a defined variable. Here is a simple
example that demonstrates how the command works −
#!/bin/sh

NAME="Zara Ali"
unset NAME
echo $NAME
The above example does not print anything. You cannot use the unset command
to unset variables that are marked readonly.

Variable Types

When a shell is running, three main types of variables are present −


 Local Variables − A local variable is a variable that is present within the
current instance of the shell. It is not available to programs that are started
by the shell. They are set at the command prompt.
 Environment Variables − An environment variable is available to any
child process of the shell. Some programs need environment variables in
order to function correctly. Usually, a shell script defines only those
environment variables that are needed by the programs that it runs.
 Shell Variables − A shell variable is a special variable that is set by the
shell and is required by the shell in order to function correctly. Some of
these variables are environment variables whereas others are local
variables.
3.3 Argument Processing
Consider the following bash command. The
command name is a.sh. The command line has three
parameters: one, two, and three four.

26
Unit-3:Shell Programming

$sh a.sh one two "three four"

Positional parameters are delimited by a space. The shell interprets the things after
the spaces as individual parameters. If the parameter itself contains a space,
enclose it in quotation marks, as in "three four," above.

While a.sh is running, bash provides it with the


following shell variables:

Variable name Value

$0 a.sh
$1 one
$2 two
$3 three four
$# 3
$@ one two three four
$* one two three four

The variable $0 is set to the first word of the


command — the command name. This variable is
useful because commands can be renamed, or
executed using a symbolic link. Some programs
behave differently depending on the command name
used to run the program. $0 allows a program to see
what command name launched it.

The variables $1, $2, and $3 contain the values of the


first, second, and third parameters, respectively. If
27
Unit-3:Shell Programming

there was a fourth parameter, its value would be


placed in the variable $4. Parameters greater than 9
can be accessed by using curly braces around the
number; for instance, ${10} would be the tenth
parameter, and ${123} would be the 123rd.

The variable $# contains the number of positional


parameters, excluding $0.

The variable $@ contains the value of all positional


parameters, excluding $0.

The variable $* is the same as $@, except when it is


double-quoted. When enclosed in double
quotes, $* expands to $1c$2c$3c... where c is the
first character of $IFS, bash's internal field separator
variable. The IFS is used for word splitting, and its
default value is "space, tab, or newline" — this is
where bash sees the beginning and end of one word.

If the value of $IFS is "_"


(an underscore), "$@" expands to:

one two three four

Whereas "$*" expands to:

one_two_three four

Positional Parameters

28
Unit-3:Shell Programming

Here are examples of using positional parameters in


bash.

Using the set built-in command, the value of $@ can


be modified for the current shell. Everything after set
-- is registered as a positional parameter.

set -- one two "three four"

Now we can iterate over these variables


using for ... in:

for arg in $@; do echo "$arg"; done

one

two

three four

In bash, $@ is the default list to iterate when you


run for, so this command also works:

for arg; do echo "$arg"; done

one

two

29
Unit-3:Shell Programming

three four

Iterating over "$*" (with double quotes) provides


a concatenated string of positional parameters, joined
with the first character of $IFS:

IFS=","; for arg in "$*"; do echo "$arg"; done

one_two_three four

You can create as many positional parameters as you wish, but you can access only
9 variables at a time.

Eg.

$set a b c d e f g h I j k l m n o p q r s t

Here total 20 positional parameters are created. But you can access only nine
parameters.

$echo $1 $9

aI

$echo $10

a0

Here $1 is evaluated to a and 0 is printed straight way.

30
Unit-3:Shell Programming

However, with help of shift command you can delete parameters from beginning.

shift and shift 1 are same.

$shift

Here 1st positional parameter is deleted

$echo $9

$shift 2

Here b and c will be deleted.

$echo $9

3.4 Shell’s interpretation at prompt

When we log in, the $ sign will be visible in the shell terminal (# prompt if logged
in as root or administrator). The Bash shell runs scripts as interpreter. Whenever
we type a command, the BASH shell will read them as series of words (tokens).
Each word is separated by a space (), semi colon (;), or any other command
delimiter. We terminate the command by pressing the Enter key. This will insert a
new line character at the end of the command. The first word is taken as a
command, then consecutive words are treated as options or parameters.

The shell processes the command line as follows:

 If applicable, substitution of history commands


 Converting command line into tokens and words

31
Unit-3:Shell Programming

 Updating history
 Processing of quotes
 Defining functions and substitution of alias
 Setting up of pipes, redirection, and background
 Substitution of variables (such as $name and $user) is performed
 Command substitution (echo`cal` and echo`date`) is performed
 Globing is performed...

Get all the quality content you’ll ever need to stay ahead with a Packt subscription
- access over 7,500 online books and videos on everything in tech

In the keyboard, there is one interesting key, the backward quote such as "`". This
key is normally situated below the Esc key. If we place text between two
successive back quotes, then echo will execute those as commands instead of
processing them as plane text.

Alternate syntax for $(command) is the backtick character "`", which we can see as
follows:

$(command) or `command`

For example:

 We need to use proper double quoted inverted commas, as follows:

$ echo "Hello, whoami"

The next command will print the text as it is; such as Hello, whoami:

Hello, who am i

Use proper double inverted commas:

$ echo "Hello, `whoami`."


Hello, student

When we enclose whoami text in the "`" character, the same text which was
printed as plain text will run as a command, and the command output will be
printed on screen.

Use proper double inverted commas:

32
Unit-3:Shell Programming

 $ echo "Hello, $(whoami)."


 Hello, student.
 Same like the earlier explanation.

Another example:

echo "Today is date"

Output:

Today is date

Command separators

Commands can also be combined in such a way that they are executed in a
particular sequence.

Command1; command2

A command line can consist of multiple commands. Each command is separated


by a semicolon, and the command line is terminated with a newline. The exit status
is that of the last command in the chain of commands.

The first command is executed, and the second one is started as soon as the first
one has finished.

$ w; date

Output:

$ w ; date > whoandwhen

Output of the date command will be redirected to the whoandwhen file.

33
Unit-3:Shell Programming

In the preceding example, we can see that when we put multiple commands on the
same line, but separated by the ";" command, then those commands execute
sequentially one by one.

$ date; who am i
Tue Mar 10 23:21:38 PDT 201
student pts/0 2015-03-10 23:12 (:0.0)

In the preceding example, the date command is executed first and the who am I
command will be executed next. Both the commands are typed on same lines,
separated by the ";"" command...

We have already used pipes in many earlier sessions. It is a tool for inter-process
communication.

$ command_1 | command_2

In this case, the output of command_1 will be send as an input to command_2. The
limitation is that the communication is half duplex. This means the data can flow in
only one direction. Normally for inter-process communication, you need to open
files then get the file descriptor. This will be used to write to the pipe file. Again,
we need to create a Fifo file by special commands. The preceding technique
simplifies all this process. We only need to insert "|" in between the two processes.
The operating system creates one intermediate buffer. This buffer is used for
storing the data from one command and will be used again for the second
command.

A simple example is as follows:

$ who | wc

The preceding simple command will be carrying out three different activities. First,
it will copy the output of the who command to the temporary file. Then the wc
command will read no of lines, means here count of total users who are logged in.

3.5 Arithmetic Expression Evaluation

There are various operators supported by each shell. We will discuss in detail
about Bourne shell (default shell) in this chapter.
We will now discuss the following operators −
34
Unit-3:Shell Programming

 Arithmetic Operators
 Relational Operators
 Boolean Operators
 String Operators
 File Test Operators
Bourne shell didn't originally have any mechanism to perform simple arithmetic
operations but it uses external programs, either awk or expr.
The following example shows how to add two numbers −
#!/bin/sh

val=`expr 2 + 2`
echo "Total value : $val"
The above script will generate the following result −
Total value: 4
The following points need to be considered while adding −
 There must be spaces between operators and expressions. For example, 2+2
is not correct; it should be written as 2 + 2.
 The complete expression should be enclosed between ‘ ‘, called the
backtick.

Arithmetic Operators

The following arithmetic operators are supported by Bourne Shell.


Assume variable a holds 10 and variable b holds 20 then −
Show Examples

Operator Description Example

+ (Addition) Adds values on `expr $a + $b` will give 30

either side of the operator

35
Unit-3:Shell Programming

- (Subtraction) Subtracts right hand operand `expr $a - $b` will give -10

from left hand operand

* (Multiplication) Multiplies values on `expr $a \* $b` will give 200

either side of the operator

/ (Division) Divides left hand `expr $b / $a` will give 2

operand by right hand


operand

% (Modulus) Divides left hand operand `expr $b % $a` will give 0

by right hand operand and


returns remainder

= (Assignment) Assigns right operand a = $b would assign value of b

in left operand into a

== (Equality) Compares two numbers, [ $a == $b ] would return false.

if both are same then returns


true.

!= (Not Equality) Compares two numbers, if [ $a != $b ] would return true.


both

are different then returns true.

36
Unit-3:Shell Programming

It is very important to understand that all the conditional expressions should be


inside square braces with spaces around them, for example [ $a == $b ] is correct
whereas, [$a==$b] is incorrect.
All the arithmetical calculations are done using long integers.

Relational Operators

Bourne Shell supports the following relational operators that are specific to
numeric values. These operators do not work for string values unless their value is
numeric.
For example, following operators will work to check a relation between 10 and 20
as well as in between "10" and "20" but not in between "ten" and "twenty".

Operator Description

-eq Checks if the value of two operands are equal or not; if yes, then the condition
becomes true.

-ne Checks if the value of two operands are equal or not; if values are not equal, then
the condition becomes true.

-gt Checks if the value of left operand is greater than the value of right operand; if
yes, then the condition becomes true.

-lt Checks if the value of left operand is less than the value of right operand; if yes,
then the condition becomes true.

-ge Checks if the value of left operand is greater than or equal to the value of right
operand; if yes, then the condition becomes true.

-le Checks if the value of left operand is less than or equal to the value of right

37
Unit-3:Shell Programming

operand; if yes, then the condition becomes true.

It is very important to understand that all the conditional expressions should be


placed inside square braces with spaces around them. For example, [ $a <= $b ] is
correct whereas, [$a <= $b] is incorrect.

Boolean Operators

The following Boolean operators are supported by the Bourne Shell.

Operator Description Example

! This is logical negation. This inverts a true


[ ! false ] is true.
condition into false and vice versa.

-o This is logical OR. If one of the operands is [ $a -lt 20 -o $b -gt 100 ] is true.
true,

then the condition becomes true.

-a This is logical AND. If both the operands are


true,
[ $a -lt 20 -a $b -gt 100 ] is false.
then the condition becomes true otherwise false.

String Operators

The following string operators are supported by Bourne Shell.


Assume variable a holds "abc" and variable b holds "efg" then −
Show Examples

38
Unit-3:Shell Programming

Operator Description Exa

= Checks if the value of two operands are equal [ $a = $b ] is not true.

or not; if yes, then the condition becomes true.

!= Checks if the value of two operands are equal or not; [ $a != $b ] is true.

if values are not equal then the condition becomes


true.

-z Checks if the given string operand size is zero; [ -z $a ] is not true.

if it is zero length, then it returns true.

-n Checks if the given string operand size is non-zero; [ -n $a ] is not false.

if it is nonzero length, then it returns true.

str Checks if str is not the empty string; [ $a ] is not false.

if it is empty, then it returns false.

File Test Operators

We have a few operators that can be used to test various properties associated
with a Unix file.
Assume a variable file holds an existing file name "test" the size of which is 100
bytes and has read, write and execute permission on −
Show Examples

Operator Description Example

39
Unit-3:Shell Programming

-b file Checks if file is a block special file; if yes, [ -b $file ] is false.

then the condition becomes true.

-c file Checks if file is a character special file; [ -c $file ] is false.

if yes, then the condition becomes true.

-d file Checks if file is a directory; [ -d $file ] is not true.

if yes, then the condition becomes true.

-f file Checks if file is an ordinary file as [ -f $file ] is true.


opposed

to a directory or special file; if yes,

then the condition becomes true.

-g file Checks if file has its set group ID (SGID) [ -g $file ] is false.
bit set;

if yes, then the condition becomes true.

-k file Checks if file has its sticky bit set; if yes, [ -k $file ] is false.

then the condition becomes true.

-p file Checks if file is a named pipe; if yes, [ -p $file ] is false.

then the condition becomes true.

40
Unit-3:Shell Programming

-t file Checks if file descriptor is open and [ -t $file ] is false.


associated

with a terminal; if yes, then the condition


becomes true.

-u file Checks if file has its Set User ID (SUID) [ -u $file ] is false.
bit set; if yes, then the condition becomes
true.

-r file Checks if file is readable; if yes, then the [ -r $file ] is true.


condition becomes true.

-w file Checks if file is writable; if yes, then the [ -w $file ] is true.


condition becomes true.

-x file Checks if file is executable; if yes, then [ -x $file ] is true.


the condition becomes true.

-s file Checks if file has size greater than 0; if [ -s $file ] is true.


yes, then condition becomes true.

-e file Checks if file exists; is true even if file is a [ -e $file ] is true.


directory but exists.

The test command in Unix evaluates the expression parameter. In most recent
shell implementations, it is a shell builtin, even though the external version still
exists. In the second form of the command, the [ ] (brackets) must be surrounded
by blank spaces (this is because [ is a program and POSIX compatible shells
require a space between the program name and its arguments). One must test

41
Unit-3:Shell Programming

explicitly for file names in the C shell. File-name substitution (globbing) causes the
shell script to exit.
The test command is not to be confused with the [[ reserved word that was
introduced with ksh88. The latter is not a command but part of the ksh88 syntax
and does not apply file-name substitution to glob expressions.
The version of test bundled in GNU coreutils was written by Kevin Braunsdorf
and Matthew Bradburn. The test command has also been ported to the IBM
operating system.

Syntax[

test expression

or

[ expression ]

Arguments
The following arguments are used to construct this parameter:

-e FileName - FileName exists

All remaining arguments return true if the object (file or string) exists, and the
condition specified is true.

-b Filename - Returns a True exit value if the specified FileName exists and is a
block special file
-c FileName - FileName is a character special file
-d FileName - FileName is a directory

-f FileName - FileName is a regular file


-g FileName - FileName's Set Group ID bit is set
-h FileName - FileName is a symbolic link
-k FileName - FileName's sticky bit is set
-L FileName - FileName is a symbolic link
-p FileName - FileName is a named pipe (FIFO)
-r FileName - FileName is readable by the current process
-s FileName - FileName has a size greater than 0
42
Unit-3:Shell Programming

-t FileDescriptor - FileDescriptor is open and associated with a terminal


-u FileName - FileName's Set User ID bit is set
-w FileName - FileName's write flag is on. However, the FileName will not be
writable on a read-only file system even if test indicates true
-x FileName - FileName's execute flag is on
If the specified file exists and is a directory, the True exit value indicates that the
current process has permission to change cd into the directory.

Nonstandard Korn Shell extensions:

file1 -nt file2 - file1 is newer than file2


file1 -ot file2 - file1 is older than file2
file1 -ef file2 - file1 is another name for file2 - (symbolic link or hard link)

String arguments
In Perl, these sections are reversed: eq is a string operator and == is a numerical
operator, and so on for the others.

-n String1 - the length of the String1 variable is nonzero


-z String1 - the length of the String1 variable is 0 (zero)
String1 = String2 - String1 and String2 variables are identical
String1 != String2 - String1 and String2 variables are not identical
String1 - true if String1 variable is not a null string

Number arguments

Integer1 -eq Integer2 - Integer1 and Integer2 variables are algebraically equal
-ne - not equal
-gt - greater than
-ge - greater or equal
-lt - less than
-le - less or equal

Operators
test arguments can be combined with the following operators:

! - Unary negation operator


43
Unit-3:Shell Programming

-a - Binary AND operator


-o - Binary OR operator (the -a operator has higher precedence than the -o
operator)
\(Expression\) - Parentheses for grouping must be escaped with a backslash \

The -a and -o operators, along with parentheses for grouping, are XSI
extensions and are therefore not portable. In portable shell scripts, the same effect
may be achieved by connecting multiple invocations of test together with
the && and || operators and parentheses.
Exit status
This command returns the following exit values:

0 - The Expression parameter is true


1 - The Expression parameter is false or missing
>1 - An error occurred

Examples
1. To test whether a file is nonexistent or empty, type:

if test ! -s "$1"
then
echo $1 does not exist or is empty.
fi

If the file specified by the first positional parameter to the shell procedure, $1, does
not exist or is of size 0, the test command displays the message. If $1 exists and
has a size greater than 0, the test command displays nothing.
Note: There must be a space between the -s function and the file name.
The quotation marks around $1 ensure that the test works properly even if the
value of $1 is a null string. If the quotation marks are omitted and $1 is the empty
string, the test command displays the error message:

test: argument expected.

44
Unit-3:Shell Programming

2. To do a complex comparison, type:

if ["$#" -lt 2 ] || ! [ -e "$1"]


then
exit
fi

If the shell procedure is given fewer than two positional parameters or the file
specified by $1 does not exist, then the shell procedure exits. The special shell
variable $# represents the number of positional parameters entered on the
command line that starts this shell procedure.
3.6 Control Structure
You can control the execution of Linux commands in a shell script with control
structures. Control structures allow you to repeat commands and to select certain
commands over others. A control structure consists of two major components: a
test and commands. If the test is successful, then the commands are executed. In
this way, you can use control structures to make decisions as to whether commands
should be executed.
There are two different kinds of control structures: loops and conditions. A loop
repeats commands, whereas a condition executes a command when certain
conditions are met. The BASH shell has three loop control structures: while, for,
and for-in. There are two condition structures: if and case. The control structures
have as their test the execution of a Linux command. All Linux commands return
an exit status after they have finished executing. If a command is successful, its
exit status will be 0. If the command fails for any reason, its exit status will be a
positive value referencing the type of failure that occurred. The control structures
check to see if the exit status of a Linux command is 0 or some other value. In the
case of the if and while structures, if the exit status is a zero value, then the
command was successful and the structure continues.
Test Operations
With the test command, you can compare integers, compare strings, and even
perform logical operations. The command consists of the keyword test followed by
the values being compared, separated by an option that specifies what kind of
comparison is taking place. The option can be thought of as the operator, but it is
written, like other options, with a minus sign and letter codes. For example, -eq is
the option that represents the equality comparison. However, there are two string
operations that actually use an operator instead of an option. When you compare
45
Unit-3:Shell Programming

two strings for equality you use the equal sign, =. For inequality you use !=. Table
8-6 lists some of the commonly used options and operators used by test. The
syntax for the test command is shown here:
test value -option value
test string1 = string2
Integer Comparisons Function
-gt Greater-than
-lt Less-than
-ge Greater-than-or-equal-to
-le Less-than-or-equal-to
-eq Equal
-ne Not-equal
String Comparisons
-n string True if length of string is non-zero

-z string True if length of string is zero

string1 == string2 True if the strings are equal

string1 != string2 True if the strings are not equal

Logical Operations
-a Logical AND
-o Logical OR
! Logical NOT
File Tests
-f File exists and is a regular file
-s File is not empty
-r File is readable
-w File can be written to, modified
-x File is executable
46
Unit-3:Shell Programming

Integer Comparisons Function


-d Filename is a directory name
-r file True if the file exists and is readable
-s file True if the file exists and has a size greater
than zero
-t fd True if the file descriptor is open refers to the
terminal
-u file True if the file exists and its “set user ID” bit
is set
-w file True if the file exists and is writable
-x file True if the file exists and is executable
-O file True if the file exists and is owned the
effective user ID of the user.
-G file True if the file exists and is owned the
effective group ID of the user.
-L file True if the file exists and is a symbolic link
-N file True if the file exists and has been modified
since it was last read
-S file True if the file exists and is a named socket

In the next example, the user compares two integer values to see if they are equal.
In this case, you need to use the equality option, -eq. The exit status of the test
command is examined to find out the result of the test operation. The shell special
variable $? holds the exit status of the most recently executed Linux command.
$ num=5
$ test $num -eq 10
$ echo $?
1
Instead of using the keyword test for the test command, you can use enclosing
brackets. The command test $greeting = "hi" can be written as
$ [ $greeting = "hi" ]

47
Unit-3:Shell Programming

Similarly, the test command test $num -eq 10 can be written as


$ [ $num -eq 10]
The brackets themselves must be surrounded by white space: a space, TAB, or
ENTER. Without the spaces, it would be invalid.
Conditional Statements: There are total 5 conditional statements which can be
used in bash programming
1. if statement
2. if-else statement
3. if..elif..else..fi statement (Else If ladder)
4. if..then..else..if..then..fi..fi..(Nested if)
5. switch statement
Their description with syntax is as follows:
if statement
This block will process if specified condition is true.
Syntax:
if [ expression ]
then
statement
fi
if-else statement
If specified condition is not true in if part then else part will be execute.
Syntax
if [ expression ]
then
statement1
else
statement2
fi
if..elif..else..fi statement (Else If ladder)
To use multiple conditions in one if-else block, then elif keyword is used in shell.
If expression1 is true then it executes statement 1 and 2, and this process
continues. If none of the condition is true then it processes else part.
Syntax

if [ expression1 ]
then

48
Unit-3:Shell Programming

statement1
statement2
.
.
elif [ expression2 ]
then
statement3
statement4
.
.
else
statement5
fi
if..then..else..if..then..fi..fi..(Nested if)
Nested if-else block can be used when, one condition is satisfies then it again
checks another condition. In the syntax, if expression1 is false then it processes
else part, and again expression2 will be check.
Syntax:
if [ expression1 ]
then
statement1
statement2
.
else
if [ expression2 ]
then
statement3
.
fi
fi
switch statement
case statement works as a switch statement if specified value match with the
pattern then it will execute a block of that particular pattern
When a match is found all of the associated statements until the double semicolon
(;;) is executed.
A case will be terminated when the last command is executed.
If there is no match, the exit status of the case is zero.
Syntax:
case in
Pattern 1) Statement 1;;
49
Unit-3:Shell Programming

Pattern n) Statement n;;


esac
Example Programs
Example 1:
Implementing if statement
filter_none
brightness_4

#Initializing two variables

a=10

b=20

#Check whether they are equal

if [ $a == $b ]

then

echo "a is equal to b"

fi

#Check whether they are not equal

if [ $a != $b ]

then

echo "a is not equal to b"

50
Unit-3:Shell Programming

fi

Output
$sh main.sh
a is not equal to b
Example 2:
Implementing if. Else statement
filter_none
brightness_4

#Initializing two variables

a=20

b=20

if [ $a == $b ]

then

#If they are equal then print this

echo "a is equal to b"

else

#else print this

echo "a is not equal to b"

51
Unit-3:Shell Programming

fi

Output
$sh -f main.sh
a is equal to b
Example 3:
Implementing switch statement
filter_none
brightness_4

CARS="bmw"

#Pass the variable in string

case "$CARS" in

#case 1

"mercedes") echo "Headquarters - Affalterbach,


Germany" ;;

#case 2

"audi") echo "Headquarters - Ingolstadt, Germany" ;;

#case 3

"bmw") echo "Headquarters - Chennai, Tamil Nadu,

52
Unit-3:Shell Programming

India" ;;

esac

Output
$sh -f main.sh
Headquarters - Chennai, Tamil Nadu, India.
When we need to perform multilevel checks, we can use multiple if and else
conditions or nested if-else branches but when we need to perform all conditional
operations on a particular variable then it better to use switch case. In shell
scripting switch case is represented using keywords case and esac which will do
multilevel branching and checking in a better way than multiple if-else conditions.
Switch case will need an expression which it needs to evaluate and need to perform
multiple operations based on the outcome of the expression. So, we will use a
switch case conditional statement when we want to perform different operations on
the outcome of a single expression.

Syntax for Switch Case in Shell Scripting


The syntax for the switch case in shell scripting can be represented in two ways

one is single pattern expression and multi-pattern expression let’s have a look now.

First Syntax
Now, we will have a look at the syntax of the switch case conditional statement

with a single pattern.

Syntax:

case $var in pattern) commands to execute;;

pattern1) commands to execute;;

53
Unit-3:Shell Programming

pattern2) commands to execute;;

pattern3) commands to execute;;

*)

Default condition and commands to execute;;

esac

In the above switch case syntax, $var in the pattern is a conditional expression if it

evaluates to true commands corresponding to it will execute like that it will check

for all conditional patterns if nothing satisfies or evaluates to true then commands

in default condition will execute. The default condition is optional but it better to

have it. When one condition matches then “;” indicates control needs to go the end

of the switch case statement.

Second Syntax
Now, we will have a look at the syntax of the switch case conditional statement

with multiple patterns.

Syntax:

case $var in pattern|pattern1|pattern2) list of commands need to execute;;

pattern3| pattern4| pattern5) list of commands need to execute;;

54
Unit-3:Shell Programming

pattern6) commands need to execute;;

*)

Default condition and statements need to execute

esac

In the above switch case syntax method, we are having a single $var comparing

against multiple patterns with an or condition. If one of the condition matches it

evaluates to true then corresponding statements will execute until the “;” which

indicates the end of that conditional statement. *) indicates the start of the default

condition and statements need to execute and esac indicates the end of the switch

case. We can include wild characters, regex in the patterns. The conditional check

will happen continuously until it finds a pattern otherwise default statement will

execute.

The following is an Example of a switch case program:


echo “Enter a number”

read num

case $num in

[0-9])

echo “you have entered a single digit number”

;;
55
Unit-3:Shell Programming

[1-9][1-9])

echo “you have entered a two-digit number”

;;

[1-9][1-9][1-9])

echo “you have entered a three-digit number”

;;

*)

echo “your entry does not match any of the conditions”

;;

Esac

Example-2

echo"Please talk to me ..."


while :
do
read INPUT_STRING
case $INPUT_STRING in
hello)
echo"Hello yourself!"
;;
bye)
echo"See you again!"
break
;;
*)
echo"Sorry, I don't understand"
;;
esac

56
Unit-3:Shell Programming

done
echo
echo"That's all folks!"

The while construct allows for repetitive execution of a list of commands, as long
as the command controlling the while loop executes successfully (exit status of
zero). The syntax is:

while CONTROL-COMMAND; do CONSEQUENT-COMMANDS; done

CONTROL-COMMAND can be any command(s) that can exit with a success or


failure status. The CONSEQUENT-COMMANDS can be any program, script or
shell construct.

As soon as the CONTROL-COMMAND fails, the loop exits. In a script, the


command following the done statement is executed.

The return status is the exit status of the last CONSEQUENT-


COMMANDS command, or zero if none was executed.

Simple example using while

Here is an example for the impatient:

#!/bin/sh

# This script opens 4 terminal windows.

i="0"

while [ $i -lt 4 ]
do
xterm &
i=$[ $i + 1 ]
done

57
Unit-3:Shell Programming

Nested while loops

The example below was written to copy pictures that are made with a webcam to a
web directory. Every five minutes a picture is taken. Every hour, a new directory is
created, holding the images for that hour. Every day, a new directory is created
containing 24 subdirectories. The script runs in the background.

#!/bin/sh

# This script copies files from my homedirectory into the webserver directory.
# (use scp and SSH keys for a remote directory)
# A new directory is created every hour.

PICSDIR=/home/carol/pics
WEBDIR=/var/www/carol/webcam

while true
do
DATE=`date +%Y%m%d`
HOUR=`date +%H`
mkdir $WEBDIR/"$DATE"

while [ $HOUR -ne "00" ]; do


DESTDIR=$WEBDIR/"$DATE"/"$HOUR"
mkdir "$DESTDIR"
mv $PICDIR/*.txt "$DESTDIR"/
sleep 3600
HOUR=`date +%H`
done
done

Note the use of the true statement. This means: continue execution until we are
forcibly interrupted (with kill or Ctrl+C).

This small script can be used for simulation testing; it generates files:

58
Unit-3:Shell Programming

#!/bin/sh

# This generates a file every 5 minutes

while true
do
touch pic-`date +%s`.txt
sleep 300
done

Note the use of the date command to generate all kinds of file and directory
names. See the man page for more.

Use the system

The previous example is for the sake of demonstration. Regular checks can
easily be achieved using the system's cron facility. Do not forget to redirect
output and errors when using scripts that are executed from your crontab!
Using keyboard input to control the while loop

This script can be interrupted by the user when a Ctrl+C sequence is entered:

#!/bin/sh

# This script provides wisdom

FORTUNE=/usr/games/fortune

while true; do
echo "On which topic do you want advice?"
cat << topics
politics
startrek
kernelnewbies
sports
bofh-excuses
magic

59
Unit-3:Shell Programming

love
literature
drugs
education
topics

echo
echo -n "Make your choice: "
read topic
echo
echo "Free advice on the topic of $topic: "
echo
$FORTUNE $topic
echo

done

A here document is used to present the user with possible choices. And again,
the true test repeats the commands from the CONSEQUENT-COMMANDS list
over and over again.

Calculating an average

This script calculates the average of user input, which is tested before it is
processed: if input is not within range, a message is printed. If q is pressed, the
loop exits:

#!/bin/bash

# Calculate the average of a series of numbers.

SCORE="0"
AVERAGE="0"
SUM="0"
NUM="0"

while true; do

60
Unit-3:Shell Programming

echo -n "Enter your score [0-100%] ('q' for quit): "; read SCORE;

if (("$SCORE" < "0")) || (("$SCORE" > "100")); then


echo "Be serious. Common, try again: "
elif [ "$SCORE" == "q" ]; then
echo "Average rating: $AVERAGE%."
break
else
SUM=$[$SUM + $SCORE]
NUM=$[$NUM + 1]
AVERAGE=$[$SUM / $NUM]
fi

done

echo "Exiting."

Note how the variables in the last lines are left unquoted in order to do arithmetic.
while loop syntax
The syntax is as follows:

While [ condition]
do
command1
command2
command3
done
command1 to command3 will be executed repeatedly till condition is true. The
argument for a while loop can be any boolean expression. Infinite loops occur
when the conditional never evaluates to false. Here is the while loop one-liner
syntax:

while [ condition ]
do commands
done
while control-command
do COMMANDS

61
Unit-3:Shell Programming

done
For example following while loop will print welcome 5 times on screen:

#!/bin/sh
x=1
while [ $x –le 5 ]
do
echo "Welcome $x times"
x=$(($x + 1))
done
And here is above code as a bash while one liner:
x=1
while [ $x -le 5 ]
do
echo "Welcome $x times"
x=`expr $x + 1`
done
Here is a sample shell code to calculate factorial using while loop:
#!/bin/sh
counter=$1
factorial=1
while [ $counter –gt 0 ]
do
factorial=`expr $factorial \* 1`
counter=`expr $counter – 1`
done
echo $factorial
To run just type:
$ sh script.sh 5

While loops are frequently used for reading data line by line from file:
#!/bin/sh
FILE=$1
# read $FILE using the file descriptors
Exec 3 < &0
Exec 0 < $FILE
While read line
do
62
Unit-3:Shell Programming

# use $line variable to process line


Echo $line
done
exec0 < &3
You can easily evaluate the options passed on the command line for a script using
while loop:

Redirecting user input for a while Loop

How about reading user input from a file? Say you have a file as follows with
various IP address:
cat bad-guys.ips.txt
List of crackers IP address:
192.168.3.50#BLOCK: www-2

185.220.101.206#Block: hacker

91.192.103.26#Block:smptd hacker

46.19.141.85#Block:sending too many www requests

Here is while loop that read those IP address separated by Internal Field Separator
($IFS) to an octothorpe (#):
#!/bin/bash

# Script name: block_ips.sh

# Set the Internal Field Separator to an octothorpe '#'


IFS='#'

# Set input file name here


INPUT="bad-guys.ips.txt"

# Read file line-by-line to get an IP and comment to block it using the iptables
While read -rip comment

63
Unit-3:Shell Programming

do
/sbin/iptables -A INPUT -s"$ip"-m comment --comment"$comment"-j
DROP

done<"$INPUT"

How do I use while as infinite loops?


Infinite for while can be created with empty expressions, such as:

#!/bin/sh
while :
do
echo"infinite loops [ hit CTRL+C to stop]"
done

Conditional while loop exit with break statement


You can do early exit with the break statement inside the whil loop. You can exit
from within a WHILE using break. General break statement inside the while loop
is as follows:

While [ condition ]
do
statements1 #Executed as long as condition is true and/or, up to a disaster-
condition if any.
statements2
if(disaster-condition)
then
break #Abandon the while lopp.
fi
statements3 #While good and, no disaster-condition.
done
In this example, the break statement will skip the while loop when user enters -1,
otherwise it will keep adding two numbers:

#!/bin/bash

64
Unit-3:Shell Programming

while :
do
read -p "Enter two numnbers ( - 1 to quit ) : " a b
if [ $a -eq -1 ]
then
break
fi
ans=$(( a + b ))
echo $ans
done

Early continuation with the continue statement


To resume the next iteration of the enclosing WHILE loop use the continue
statement as follows:

While [ condition ]
do
statements1 #Executed as long as condition is true and/or, up to a disaster-
condition if any.
statements2
if(condition)
then
continue #Go to next iteration of I in the loop and skip statements3
fi
statements3
done

Loops are one of the fundamental concepts of programming languages. Loops are
handy when you want to run a series of commands a number of times until a
particular condition is met.

In scripting languages such as Bash, loops are useful for automating repetitive
tasks. There are three basic loop constructs in Bash scripting, for loop , whileloop,
and until loop .

This tutorial covers the basics of while loops in Bash. We’ll also show you how to
use the break and continue statements to alter the flow of a loop.

Bash while Loop

65
Unit-3:Shell Programming

The while loop is used to performs a given set of commands an unknown number
of times as long as the given condition evaluates to true.

The Bash while loop takes the following form:

While [CONDITION]
do
[COMMANDS]
done
Copy

The while statement starts with the while keyword, followed by the conditional
expression.

The condition is evaluated before executing the commands. If the condition


evaluates to true, commands are executed. Otherwise, if the condition evaluates to
false, the loop is terminated, and the program control will be passed to the
command that follows.

In the example below, on each iteration, the current value of the variable i is
printed and incremented by one.

i=0

while [ $i -le 2 ]
do
echo Number: $i
((i++))
done
Copy

Tue loop iterates as long as i is less or equal than two. It will produce the following
output:

Number: 0
Number: 1
Number: 2

Infinite while Loop

66
Unit-3:Shell Programming

An infinite loop is a loop that repeats indefinitely and never terminates. If the
condition always evaluates to true, you get an infinite loop.

In the following example, we are using the built-in command : to create an infinite
loop. : always returns true. You can also use the true built-in or any other statement
that always returns true.

while :
do
echo"Press <CTRL+C> to exit."
sleep 1
done
Copy

The while loop above will run indefinitely. You can terminate the loop by
pressing CTRL+C.

Here is a single-line equivalent:

while:; doecho’Press <CTRL+C> to exit.'; sleep 1;done


Copy

Read a File Line By Line

One of the most common usages of the while loop is to read a file, data stream, or
variable line by line.

Here is an example that reads the /etc/passwd file line by line and prints each line:

file=/etc/passwd

while read -r line


do
echo $line
done < "$file"
Copy

Instead of controlling the while loop with a condition, we are using input
redirection (< "$file") to pass a file to the read command, which controls the loop.
The while loop will run until the last line is read.

67
Unit-3:Shell Programming

When reading file line by line, always use read with the -r option to prevent
backslash from acting as an escape character.

By default, the read command trims the leading/trailing whitespace characters


(spaces and tabs). Use the IFS= option before read to prevent this behavior:

file=/etc/passwd

while IFS=read -r line;


do
echo $line
done < "$file"
Copy

break and continue Statements

The break and continue statements can be used to control the while loop execution.

break Statement

The break statement terminates the current loop and passes program control to the
command that follows the terminated loop. It is usually used to terminate the loop
when a certain condition is met.

In the following example, the execution of the loop will be interrupted once the
current iterated item is equal to 2.

i=0

while [$i -lt 5]


do
echo "Number: $i"
((i++))
if[ [ "$i"== '2' ]];
then
break
fi
done

echo 'All Done!'

68
Unit-3:Shell Programming

Copy
Number: 0
Number: 1
All Done!
continue Statement

The continue statement exits the current iteration of a loop and passes program
control to the next iteration of the loop.

In the following below, once the current iterated item is equal


to 2 the continue statement will cause execution to return to the beginning of the
loop and to continue with the next iteration.

i=0

while [ $i -lt 5 ]
do
((i++))
if[ [ "$i" == '2' ]]
then
continue
fi
echo"Number: $i"
done

echo'All Done!'
Copy
Number: 1
Number: 3
Number: 4
Number: 5
All Done!

Conclusion #

The while loop repeatedly executes a given set of commands as long as a condition
is true.

69
Unit-3:Shell Programming

The while loop is perfect for a situation where you need to execute a set of
commands while some condition is true. Sometimes you need to execute a set of
commands until a condition is true.

Syntax

until command
do
Statement(s) to be executed until command is true
done
Here the Shell command is evaluated. If the resulting value is false,
given statement(s) are executed. If the command is true then no statement will be
executed and the program jumps to the next line after the done statement.

Example

Here is a simple example that uses the until loop to display the numbers zero to
nine −
#!/bin/sh

a=0

until[! $a -lt 10]


do
echo $a
a=`expr $a + 1`
done
Upon execution, you will receive the following result −
0
1
2
3
4
5
6
7
8
9

70
Unit-3:Shell Programming

The while loop vs the until loop

1. The until loop executes until a nonzero status is returned.


2. The while command executes until a zero status is returned.
3. The until loop always executes at least once.
Example
Create a shell script called until.sh:

#!/bin/bash
i=1
until [$i -gt 6]
do
echo "Welcome $i times."
i=$(( i+1 ))
done

Save and close the file. Run it as follows:

chmod +x until.sh
./until.sh

Sample outputs:

Welcome 1 times.
Welcome 2 times.
Welcome 3 times.
Welcome 4 times.
Welcome 5 times.
Welcome 6 times.

The loop in the above example initializes the variable i to 1, and then increments
and displays out the message until it equals 6. ← : infinite while
loop • Home • select loop →

71
Unit-3:Shell Programming

For Loops

Most languages have the concept of loops: If we want to repeat a task twenty
times, we don't want to have to type in the code twenty times, with maybe a slight
change each time.
As a result, we have for and while loops in the Bourne shell. This is somewhat
fewer features than other languages, but nobody claimed that shell programming
has the power of C.

for loops iterate through a set of values until the list is exhausted:
for.sh#!/bin/sh
for i in 1 2 3 4 5
do
echo "Looping ... number $i"
done
Try this code and see what it does. Note that the values can be anything at all:

for2.sh
#!/bin/sh
for i in hello 1 * 2 goodbye
do
echo "Looping ... i is set to $i"
done
This is well worth trying. Make sure that you understand what is happening here.
Try it without the * and grasp the idea, then re-read the Wildcards section and try it
again with the * in place. Try it also in different directories, and with
the * surrounded by double quotes, and try it preceded by a backslash (*)
In case you don't have access to a shell at the moment (it is very useful to have a
shell to hand whilst reading this tutorial), the results of the above two scripts are:

Looping .... number 1


Looping .... number 2
Looping .... number 3
Looping .... number 4
Looping .... number 5

72
Unit-3:Shell Programming

and, for the second example - assuming your current directory contains files named
"alpha" and "beta" and maybe other names too:
Looping ... i is setto hello
Looping ... i issetto1
Looping ... i issetto alpha
Looping ... i issetto beta
Looping ... i issetto (nameof third fileincurrentdirectory)
... etc ...
Looping ... i issetto (nameoflastfileincurrentdirectory)
Looping ... i issetto2
Looping ... i issetto goodbye

The for loop moves through a specified list of values until the list is exhausted.

1) Syntax:

Syntax of for loop using in and list of values is shown below. This for loop
contains a number of variables in the list and will execute for each item in the list.
For example, if there are 10 variables in the list, then loop will execute ten times
and value will be stored in varname.

Look at the above syntax:

o Keywords are for, in, do, done


o List is a list of variables which are separated by spaces. If list is not
mentioned in the for statement, then it takes the positional parameter value
that were passed into the shell.
o Varname is any variable assumed by the user.

Example for:

We have shown an example to count 2's table within for loop.

73
Unit-3:Shell Programming

Look at the above snapshot, our varname is table, list is specified under curly
braces. Within the curly braces, first two will initialize the table from 2, 20
represents maximum value of $table and last 2 shows the increment by value 2.

Look at the above snapshot, it displays the 2's table as the output.

2) Syntax:

Syntax of for like C programming language.

Look at the above snapshot, condition1 indicates initialization, cond2


indicates condition and cond3 indicates updation.

74
Unit-3:Shell Programming

Example for:

We have shown an example to count the number in reverse direction.

Look at the above snapshot, this is the loop script. $i will initialize with 10 and will
go till 1, decrementing with 1 value.

Look at the above snapshot, this is the output of the script.

3.7 Redirection

What is Redirection?

Redirection is a feature in Linux such that when executing a command, you can
change the standard input/output devices. The basic workflow of any Linux
command is that it takes an input and give an output.

 The standard input (stdin) device is the keyboard.


 The standard output (stdout) device is the screen.
75
Unit-3:Shell Programming

With redirection, the above standard input/output can be changed.

Here , we will learn-

 Output Redirection
 Input redirection
 File Descriptors (FD)
 Error Redirection
 Why Error Redirection?
 Examples

Output Redirection

The '>' symbol is used for output (STDOUT) redirection.

Example:

ls -al > listings

Here the output of command ls -al is re-directed to file "listings" instead of your
screen.

Here the output of command ls -al is re-directed to file "listings" instead of your
screen.

Note: Use the correct file name while redirecting command output to a file. If there
is an existing file with the same name, the redirected command will delete the
contents of that file and then it may be overwritten."

If you do not want a file to be overwritten but want to add more content to an
existing file, then you should use '>>' operator.

76
Unit-3:Shell Programming

You can redirect standard output, to not just files, but also devices!

$ cat music.mp3 > /dev/audio

The cat command reads the file music.mp3 and sends the output to /dev/audio
which is the audio device. If the sound configurations in your PC are correct, this
command will play the file music.mp3

Input redirection

The '<' symbol is used for input(STDIN) redirection

Example: The mail program in Linux can help you send emails from the Terminal.

You can type the contents of the email using the standard device keyboard. But if
you want to attach a File to email you can use the input re-direction operator in the
following format.

Mail -s "Subject" to-address < Filename

This would attach the file with the email, and it would be sent to the recipient.

The above examples were simple. Let's look at some advance re-direction
techniques which make use of File Descriptors.

File Descriptors (FD)

77
Unit-3:Shell Programming

In Linux/Unix, everything is a file. Regular file, Directories, and even Devices are
files. Every File has an associated number called File Descriptor (FD).

Your screen also has a File Descriptor. When a program is executed the output is
sent to File Descriptor of the screen, and you see program output on your monitor.
If the output is sent to File Descriptor of the printer, the program output would
have been printed.

Error Redirection

Whenever you execute a program/command at the terminal, 3 files are always


open, viz., standard input, standard output, standard error.

These files are always present whenever a program is run. As explained before a
file descriptor, is associated with each of these files.

File File Descriptor

Standard Input STDIN 0

Standard Output STDOUT 1

Standard Error STDERR 2

78
Unit-3:Shell Programming

By default, error stream is displayed on the screen. Error redirection is routing the
errors to a file other than the screen.

Why Error Redirection?

Error re-direction is one of the very popular features of Unix/Linux.

Frequent UNIX users will reckon that many commands give you massive amounts
of errors.

 For instance, while searching for files, one typically gets permission denied
errors. These errors usually do not help the person searching for a particular
file.
 While executing shell scripts, you often do NOT want error messages
cluttering up the normal program output.

The solution is to re-direct the error messages to a file.

Example 1

$ myprogram 2>errorsfile

Above we are executing a program names myprogram.

The file descriptor for standard error is 2.

Using "2>" we re-direct the error output to a file named "errorfile"

Thus, program output is not cluttered with errors.

Example 2

Here is another example which uses find statement -

find. -name 'my*' 2>error.log

Using the "find" command, we are searching the "." current directory for a file with
"name" starting with "my"

79
Unit-3:Shell Programming

Example 3 Let's see a more complex example,

Server Administrators frequently, list directories and store both error and standard
output into a file, which can be processed later. Here is the command.

ls Documents ABC> dirlist 2>&1

Here,

 which writes the output from one file to the input of another file. 2>&1
means that STDERR redirects to the target of STDOUT (which is the file
dirlist)
 We are redirecting error output to standard output which in turn is being re-
directed to file dirlist. Hence, both the output is written to file dirlist

80
Unit-3:Shell Programming

Summary

 Each file in Linux has a corresponding File Descriptor associated with it


 The keyboard is the standard input device while your screen is the standard
output device
 ">" is the output redirection operator. ">>" appends output to an existing file
 "<" is the input redirection operator
 ">&"re-directs output of one file to another.
 You can re-direct error using its corresponding File Descriptor 2.
 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.

81
Unit-3:Shell Programming

COMMAND <<InputComesFromHERE
...
...
...
InputComesFromHERE

 A limit string delineates (frames) the command list. The special


symbol << precedes the limit string. This has the effect of redirecting the
output of a command block into the stdin of the program or command. It is
similar to interactive-program < command-file, where command-
file contains

command #1
command #2
...

 The here document equivalent looks like this:

interactive-program <<LimitString
command #1
command #2
...
LimitString

 Choose a limit string sufficiently unusual that it will not occur anywhere in
the command list and confuse matters.
 Note that here documents may sometimes be used to good effect with non-
interactive utilities and commands, such as, for example, wa ll.
 Example 19-1. broadcast: Sends message to everyone logged in

#!/bin/bash

wall <<zzz23EndOfMessagezzz23
E-mail your noontime orders for pizza to the system administrator.
(Add an extra dollar for anchovy or mushroom topping.)
# Additional message text goes here.
# Note: 'wall' prints comment lines.
zzz23EndOfMessagezzz23

82
Unit-3:Shell Programming

# Could have been done more efficiently by


# wall <message-file
# However, embedding the message template in a script
#+ is a quick-and-dirty one-off solution.

exit

 Even such unlikely candidates as the vi text editor lend themselves to here
documents.
 Example 19-2. dummyfile: Creates a 2-line dummy file

#!/bin/bash

# Noninteractive use of 'vi' to edit a file.


# Emulates 'sed'.

E_BADARGS=85

if [ -z "$1" ]
then
echo "Usage: `basename $0` filename"
exit $E_BADARGS
fi

TARGETFILE=$1

# Insert 2 lines in file, then save.


#--------Begin here document-----------#
vi $TARGETFILE <<x23LimitStringx23
i
This is line 1 of the example file.
This is line 2 of the example file.
^[
ZZ
x23LimitStringx23
#----------End here document-----------#

# Note that ^[ above is a literal escape


#+ typed by Control-V <Esc>.

83
Unit-3:Shell Programming

# Bram Moolenaar points out that this may not work with 'vim'
#+ because of possible problems with terminal interaction.

exit

 The above script could just as effectively have been implemented with ex,
rather than vi. Here documents containing a list of ex commands are
common enough to form their own category, known as ex scripts.

#!/bin/bash
# Replace all instances of "Smith" with "Jones"
#+ in files with a ".txt" filename suffix.

ORIGINAL=Smith
REPLACEMENT=Jones

for word in $(fgrep -l $ORIGINAL *.txt)


do
# -------------------------------------
ex $word <<EOF
:%s/$ORIGINAL/$REPLACEMENT/g
:wq
EOF
# :%s is the "ex" substitution command.
# :wq is write-and-quit.
# -------------------------------------
done

 Analogous to "ex scripts" are cat scripts.


 Example 19-3. Multi-line message using cat

#!/bin/bash

# 'echo' is fine for printing single line messages,


#+ but somewhat problematic for for message blocks.
# A 'cat' here document overcomes this limitation.

cat <<End-of-message

84
Unit-3:Shell Programming

-------------------------------------
This is line 1 of the message.
This is line 2 of the message.
This is line 3 of the message.
This is line 4 of the message.
This is the last line of the message.
-------------------------------------
End-of-message

# Replacing line 7, above, with


#+ cat > $Newfile <<End-of-message
#+ ^^^^^^^^^^
#+ writes the output to the file $Newfile, rather than to stdout.

exit 0

#--------------------------------------------
# Code below disabled, due to "exit 0" above.

# S.C. points out that the following also works.


echo "-------------------------------------
This is line 1 of the message.
This is line 2 of the message.
This is line 3 of the message.
This is line 4 of the message.
This is the last line of the message.
-------------------------------------"
# However, text may not include double quotes unless they are escaped.

 The - option to mark a here document limit string (<<-LimitString)


suppresses leading tabs (but not spaces) in the output. This may be useful in
making a script more readable.
 Example 19-4. Multi-line message, with tabs suppressed

#!/bin/bash
# Same as previous example, but...

# The - option to a here document <<-

85
Unit-3:Shell Programming

#+ suppresses leading tabs in the body of the document,


#+ but *not* spaces.

cat <<-ENDOFMESSAGE
This is line 1 of the message.
This is line 2 of the message.
This is line 3 of the message.
This is line 4 of the message.
This is the last line of the message.
ENDOFMESSAGE
# The output of the script will be flush left.
# Leading tab in each line will not show.

# Above 5 lines of "message" prefaced by a tab, not spaces.


# Spaces not affected by <<- .

# Note that this option has no effect on *embedded* tabs.

exit 0

 A here document supports parameter and command substitution. It is


therefore possible to pass different parameters to the body of the here
document, changing its output accordingly.
 Example 19-5. Here document with replaceable parameters

#!/bin/bash
# Another 'cat' here document, using parameter substitution.

# Try it with no command-line parameters, ./scriptname


# Try it with one command-line parameter, ./scriptname Mortimer
# Try it with one two-word quoted command-line parameter,
# ./scriptname "Mortimer Jones"

CMDLINEPARAM=1 # Expect at least command-line parameter.

if [ $# -ge $CMDLINEPARAM ]
then
NAME=$1 # If more than one command-line param,
#+ then just take the first.

86
Unit-3:Shell Programming

else
NAME="John Doe" # Default, if no command-line parameter.
fi

RESPONDENT="the author of this fine script"

cat <<Endofmessage

Hello, there, $NAME.


Greetings to you, $NAME, from $RESPONDENT.

# This comment shows up in the output (why?).

Endofmessage

# Note that the blank lines show up in the output.


# So does the comment.

exit

 This is a useful script containing a here document with parameter


substitution.
 Example 19-6. Upload a file pair to Sunsite incoming directory

#!/bin/bash
# upload.sh

# Upload file pair (Filename.lsm, Filename.tar.gz)


#+ to incoming directory at Sunsite/UNC (ibiblio.org).
# Filename.tar.gz is the tarball itself.
# Filename.lsm is the descriptor file.
# Sunsite requires "lsm" file, otherwise will bounce contributions.

E_ARGERROR=85

if [ -z "$1" ]
then

87
Unit-3:Shell Programming

echo "Usage: `basename $0` Filename-to-upload"


exit $E_ARGERROR
fi

Filename=`basename $1` # Strips pathname out of file name.

Server="ibiblio.org"
Directory="/incoming/Linux"
# These need not be hard-coded into script,
#+ but may instead be changed to command-line argument.

Password="your.e-mail.address" # Change above to suit.

ftp -n $Server <<End-Of-Session


# -n option disables auto-logon

user anonymous "$Password" # If this doesn't work, then try:


# quote user anonymous "$Password"
binary
bell # Ring 'bell' after each file transfer.
cd $Directory
put "$Filename.lsm"
put "$Filename.tar.gz"
bye
End-Of-Session

exit 0

 Quoting or escaping the "limit string" at the head of a here document


disables parameter substitution within its body. The reason for this is
that quoting/escaping the limit string effectively escapes the $, `,
and \ special characters, and causes them to be interpreted literally. (Thank
you, Allen Halsey, for pointing this out.)
 Example 19-7. Parameter substitution turned off

#!/bin/bash
# A 'cat' here-document, but with parameter substitution disabled.

88
Unit-3:Shell Programming

NAME="John Doe"
RESPONDENT="the author of this fine script"

cat <<'Endofmessage'

Hello, there, $NAME.


Greetings to you, $NAME, from $RESPONDENT.

Endofmessage

# No parameter substitution when the "limit string" is quoted or escaped.


# Either of the following at the head of the here document would have
#+ the same effect.
# cat <<"Endofmessage"
# cat <<\Endofmessage

# And, likewise:

cat <<"SpecialCharTest"

Directory listing would follow


if limit string were not quoted.
`ls -l`

Arithmetic expansion would take place


if limit string were not quoted.
$((5 + 3))

A a single backslash would echo


if limit string were not quoted.
\\

SpecialCharTest

exit

89
Unit-3:Shell Programming

 Disabling parameter substitution permits outputting literal text. Generating


scripts or even program code is one use for this.
 Example 19-8. A script that generates another script

#!/bin/bash
# generate-script.sh
# Based on an idea by Albert Reiner.

OUTFILE=generated.sh # Name of the file to generate.

# -----------------------------------------------------------
# 'Here document containing the body of the generated script.
(
cat <<'EOF'
#!/bin/bash

echo "This is a generated shell script."


# Note that since we are inside a subshell,
#+ we can't access variables in the "outside" script.

echo "Generated file will be named: $OUTFILE"


# Above line will not work as normally expected
#+ because parameter expansion has been disabled.
# Instead, the result is literal output.

a=7
b=3

let "c = $a * $b"


echo "c = $c"

exit 0
EOF
) > $OUTFILE
# -----------------------------------------------------------

# Quoting the 'limit string' prevents variable expansion


#+ within the body of the above 'here document.'
# This permits outputting literal strings in the output file.
90
Unit-3:Shell Programming

if [ -f "$OUTFILE" ]
then
chmod 755 $OUTFILE
# Make the generated file executable.
else
echo "Problem in creating file: \"$OUTFILE\""
fi

# This method also works for generating


#+ C programs, Perl programs, Python programs, Makefiles,
#+ and the like.

exit 0

 It is possible to set a variable from the output of a here document. This is


actually a devious form of command substitution.

variable=$(cat <<SETVAR
This variable
runs over multiple lines.
SETVAR
)

echo "$variable"

3.8 Background process & priorities of process


ps

Reports the process status.

Syntax

ps options

-a List information about all processes most frequently requested:


all those except process group leaders and processes not
associated with a terminal.

91
Unit-3:Shell Programming

-e List information about every process(including system processes)


now running.

-f Generate a full listing.

-l Generate a long listing.

Examples

ps

Typing ps alone would list the current running processes. Below is an example of
the output that would be generated by the ps command.

PID TTY TIME CMD


6874 pts/9 0:00 ksh
6877 pts/9 0:01 csh
418 pts/9 0:00 csh

$ ps -ef | more
UID PID PPID C STIME TTY TIME CMD
root 0 0 0 Sep 18 ? 0:17 sched
root 1 0 0 Sep 18 ? 0:54 /etc/init -
root 2 0 0 Sep 18 ? 0:00 pageout
root 3 0 0 Sep 18 ? 6:15 fsflush
root 418 1 0 Sep 18 ? 0:00 /usr/lib/saf/sac -t 300
daemon 156 1 0 Sep 18 ? 0:00 /usr/lib/nfs/statd
. . . . . . . .
One of the most commonly used flags for ps is the -f ( f for full) option, which
provides more information as shown in
the following example:

$ps -f
UID PID PPID C STIME TTY TIME CMD
amrood 6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood 6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood 3662 3657 0 08:10:53 pts/6 0:00 -ksh

92
Unit-3:Shell Programming

amrood 6892 3662 4 10:51:50 pts/6 0:00 ps –f

Here is the description of all the fileds displayed by ps -f command:


Column Description
UID User ID that this process belongs to (the person running it).
PID Process ID.
PPID Parent process ID (the ID of the process that started it).
C CPU utilization of process.
STIME Process start time.
TTY Terminal type associated with the process
TIME CPU time taken by the process.
CMD The command that started this process.

BACKGROUND JOB

In Unix, a background process executes independently of the shell, leaving the


terminal free for other work. To run a process in the background, include an &
(an ampersand) at the end of the command you use to run the job. Following are
some examples:
$ sh count.sh &
$sh back1.sh &

we can have list of following processes using below command.

$jobs

[1] 3312

[2] 3412

93
Unit-3:Shell Programming
using fg command we can bring any background process in foreground.

fg command

fg is a job control command in Unix and Unix-like operating systems that resumes
execution of a suspended process or background by bringing it to the foreground
and thus redirecting its standard input and output streams to the user's terminal.
$fg %2

<Ctrl + z>

[2] + Stopped sh back1.sh &

using <Ctrl+z> we can stop any foreground job, well we are not terminating it.

$jobs

[1] 3312

[2] + stopped sh back1.sh &

we can use bg command to put a job into background.

bg
Resume the suspended job in the background, as if it had been started
with &.

eg.

$bg %2

[2] sh back1.sh&

we can also kill the job running in background.

94
Unit-3:Shell Programming

kill

The command kill sends the specified signal to the specified process or process
group. If no signal is specified, the TERM signal is sent. The TERM signal will
kill processes which do not catch this signal. For other processes, it may be
necessary to use the KILL (9) signal, since this signal cannot be caught.
$kill %2
[2] + terminated sh back1.sh
we can also forcibly kill any background job using -9 signal.

$ kill -9 $$

Above command will kill current shell forcibly. $$ denotes PID of current shell.

we can also assign priroty to process using ps command.

nice
- run a program with modified scheduling priority
Run COMMAND with an adjusted scheduling priority. With no COMMAND,
print the current scheduling priority. ADJUST is 10 by default. Range goes from -
20 (highest priority) to 19 (lowest).
Eg .
$ nice -10 sort emp.dat &
nohup

Runs a command even if the session is disconnected or the user logs out.

Syntax

nohup command [argument...]

Most of the time you login into remote server via ssh. If you start a shell script or
command and you exit (abort remote connection), the process / command will get
killed. Sometime job or command takes a long time. If you are not sure when the
95
Unit-3:Shell Programming

job will finish, then it is better to leave job running in background. However, if you
logout the system, the job will be stopped. What do you do? In such cases jobs ran
in background may result in Zombie state or process is called an orphan process.
This may result in system slowdown. To avoid it what to do?

Answer is simple, use nohup utility which allows to run command./process or shell
script that can continue running in the background after you log out from a shell:

Eg.

$ nohup pullftp.sh &

Zombie and Orphan Processes:

Normally, when a child process is killed, the parent process is told via a SIGCHLD
signal. Then the parent can do some
other task or restart a new child as needed. However, sometimes the parent process
is killed before its child is killed. In
this case, the "parent of all processes," init process, becomes the new PPID (parent
process ID). Sometime these
processes are called orphan process.
When a process is killed, a ps listing may still show the process with a Z state. This
is a zombie, or defunct, process.
The process is dead and not being used. These processes are different from orphan
processes. They are the processes that
has completed execution but still has an entry in the process table.

Daemon Processes:
Daemons are system-related background processes that often run with the
permissions of root and services requests from
other processes.
A daemon process has no controlling terminal. It cannot open /dev/tty. If you do a
"ps -ef" and look at the tty field, all
daemons will have a ? for the tty.
More clearly, a daemon is just a process that runs in the background, usually
waiting for something to happen that it is
capable of working with, like a printer daemon is waiting for print commands.

96
Unit-3:Shell Programming

If you have a program which needs to do long processing then its worth to make it
a daemon and run it in background.
LIST OF DAEMON PROCESSES

Process Description

init[ The Unix program which spawns all other processes.

biod Works in cooperation with the remote nfsd to handle client NFS requests.

crond Time-based job scheduler, runs jobs in the background.

dhcpd Dynamically configure TCP/IP information for clients.

Provides a network interface for the finger protocol, as used by


fingerd
the finger command.

Conditional Execution of Commands.

Use of && and || for running 2 commands is quite unix and found in unix only.

Due to this feature of these operators, it can open up some interesting possibilities.
Here are a few examples of how we can take advantage of this:

$ [ 5 –gt 7 ] || echo hello

hello

$ [ 5 –lt 7 ] || echo hello

97
Unit-3:Shell Programming

That means if 1st command returns false then 2nd command executes.

If 1st command returns true then 2nd command won’t execute at all.

$ [ 5 –gt 7 ] && echo hello

$ [ 5 –lt 7 ] && echo hello

hello

That means if 1st command returns true then 2nd command executes. If 1st
command returns false then 2nd command won’t execute at all.The "&&" and "||"
operators are very handy operators to use. They can save you time and make shell
scripting easier.

98

You might also like