Unit 06-Shell Programming
Unit 06-Shell Programming
$ echo $?
0
9
Defining Array Values
1. Following is the simplest method of creating an array variable. This helps assign a value to one
of its indices.
array_name[index]=value
2. Here array_name is the name of the array, index is the index of the item in the array that you
want to set, and value is the value you want to set for that item. For example:
NAME[0]="Sanjeev"
NAME[1]="Rajeev"
NAME[2]="Anil"
NAME[3]="Parveen"
NAME[4]="Anita"
3. If you are using the bash shell, here is the syntax of array initialization −
array_name=(value1 ... valuen)
4. After you have set any array variable, you access it as follows −
${array_name[index]}
#!/bin/bash The above example will 5. You can access all the items
NAME[0]="Sanjeev" generate the following result in an array in one of the
NAME[1]="Rajeev" following ways −
NAME[2]="Anil" $./test.sh ${array_name[*]}
NAME[3]="Parveen" First Index: Sanjeev ${array_name[@]}
NAME[4]="Anita" Second Index: Rajeev
echo "First Index: ${NAME[0]}"
echo "Second Index: ${NAME[1]}"
10
Environment Variables
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 command.
3 IFS Indicates the Internal Field Separator that is used by the parser for word splitting
after expansion.
4 LANG LANG expands to the default system locale; LC_ALL can be used to override this.
For example, if its value 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 colon separated list of directories
that the dynamic linker should search for shared objects when building a process
image after exec, before searching in any other directories.
6 PATH Indicates the search path for commands. It is a colon-separated list of directories
in which the shell looks for 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 for determining whether the 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.
11
Arithmetic Operators
1. Assume variable a holds 10 and variable b holds 20
Operator Description Example
+ (Addition) Adds values on either side of the operator `expr $a + $b` will give 30
- (Subtraction) Subtracts right hand operand from left hand `expr $a - $b` will give -10
operand
* (Multiplication) Multiplies values on either side of the operator `expr $a \* $b` will give 200
/ (Division) Divides left hand operand by right hand operand `expr $b / $a` will give 2
% (Modulus) Divides left hand operand by right hand operand `expr $b % $a` will give 0
and returns remainder
= (Assignment) Assigns right operand in left operand a = $b would assign value of
b into a
== (Equality) Compares two numbers, if both are same then [ $a == $b ] would return
returns true. false.
!= (Not Equality) Compares two numbers, if both are different [ $a != $b ] would return
then returns true. true.
2. It is very important to understand that all conditional expressions should be inside square braces
with spaces around them, for example [ $a == $b ] is correct whereas, [$a==$b] is incorrect.
3. All the arithmetical calculations are done using long integers.
12
Relational Operators
1. Assume variable a holds 10 and variable b holds 20
Operator Description Example
-eq Checks if the value of two operands are equal or not; if yes, [ $a -eq $b ] is not
then the condition becomes true. true.
-ne Checks if the value of two operands are equal or not; if values [ $a -ne $b ] is true.
are not equal, then the condition becomes true.
-gt Checks if the value of left operand is greater than the value of [ $a -gt $b ] is not true.
right operand; if yes, then the condition becomes true.
-lt Checks if the value of left operand is less than the value of [ $a -lt $b ] is true.
right operand; if yes, then the condition becomes true.
-ge Checks if the value of left operand is greater than or equal to [ $a -ge $b ] is not
value of right operand; if yes, then condition becomes true. true.
-le Checks if the value of left operand is less than or equal to [ $a -le $b ] is true.
value of right operand; if yes, then condition becomes true.
2. It is very important to understand that all conditional expressions should be inside square braces
with spaces around them. For example, [ $a <= $b ] is correct whereas, [$a <= $b] is incorrect.
13
Boolean and StringOperators
1. Assume variable a holds 10 and variable b holds 20
Operator Description Example
! This is logical negation. This inverts a true condition [ ! false ] is true.
into false and vice versa.
-o This is logical OR. If one of the operands is true, [ $a -lt 20 -o $b -gt 100 ] is 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.
1. Assume variable a holds "abc" and variable b holds "efg" then −
Operator Description Example
= Checks if the value of two operands are equal or not; if [ $a = $b ] is not true.
yes, then the condition becomes true.
!= Checks if the value of two operands are equal or not; if [ $a != $b ] is true.
values are not equal then the condition becomes true.
-z Checks if the given string operand size is zero; if it is zero [ -z $a ] is not true.
length, then it returns true.
-n Checks if the given string operand size is non-zero; if it is [ -n $a ] is not false.
nonzero length, then it returns true.
str Checks if str is not the empty string; if it is empty, then it [ $a ] is not false.
returns false.
14
File Test Operators
1. 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
Operator Description Example
-b file Checks if file is a block special file; if yes, then condition becomes true. [ -b $file ] is false.
-c file Checks if file is a character special file; if yes, then condition becomes true. [ -c $file ] is false.
-d file Checks if file is a directory; if yes, then condition becomes true. [ -d $file ] is not true.
-f file Checks if file is an ordinary file as opposed to a directory or special file; if [ -f $file ] is true.
yes, then the condition becomes true.
-g file Checks if file has its set group ID (SGID) bit set; if yes, then the condition [ -g $file ] is false.
becomes true.
-k file Checks if file has its sticky bit set; if yes, then condition becomes true. [ -k $file ] is false.
-p file Checks if file is a named pipe; if yes, then the condition becomes true. [ -p $file ] is false.
-t file Checks if file descriptor is open and associated with a terminal; if yes, then [ -t $file ] is false.
the condition becomes true.
-u file Checks if file has its Set User ID (SUID) bit set; if yes, then the condition [ -u $file ] is false.
becomes true.
-r file Checks if file is readable; if yes, then the condition becomes true. [ -r $file ] is true.
-w file Checks if file is writable; if yes, then the condition becomes true. [ -w $file ] is true.
-x file Checks if file is executable; if yes, then the condition becomes true. [ -x $file ] is true.
-s file Checks if file has size greater than 0; if yes, then condition becomes true. [ -s $file ] is true.
-e file Checks if file exists; is true even if file is a directory but exists. [ -e $file ] is true.
15
Shell Decision Making
The if...else statements The case...esac Statement
1. If else statements are useful 1. You can use multiple if...elif statements to perform a
decision-making statements which multiway branch. However, this is not always the best
can be used to select an option solution, especially when all of the branches depend
from a given set of options. on the value of a single variable.
2. Unix Shell supports following forms 2. Unix/Linux Shell supports case...esac statement which
of if…else statement − handles exactly this situation, and it does so more
if...fi statement efficiently than repeated if...elif statements.
if...else...fi statement 3. There is only one form of case...esac statement which
if...elif...else...fi statement has been described in detail here −
3. Most of the if statements check case...esac statement
relations using relational operators 4. The case...esac statement in the Unix shell is very
discussed in the previous chapter. similar to the switch...case statement we have in other
programming languages like C or C++.
case $1 in
dog) echo Man's best friend ;;
[aeiouAEIOU]*) echo word beginning with a vowel ;;
??) echo a two- letter word ;;
*) echo I don't know
esac
16
Linux - Shell Loop Types
1. while loop: The statements in the while loop are executed until the command in the
condition becomes false. The while loop is initialized as follows:
while command a=10
do while [ $a -gt 0 ] # a > 0
do
Statement(s) to be executed echo $a # print a
Done a=`expr $a - 2` # a = a - 1
done
2. for loop: The for loop operates on a list of items. The statements in the for loop are
executed for all items in the list. The for loop is initialized as follows:
for var in word1 word2 ... wordN for a in 10 8 6 4 2
do do
Statement(s) to be executed echo $a # print a
Done done
3. until loop: The statements in the until loop are not executed until the command in the
condition becomes true. The until loop is initialized as follows:
until command a=10
do until [ $a -lt 2 ] # a < 2
do
Statement(s) to be executed echo $a # print a
done a=`expr $a - 2` # a = a - 1
done
17
Linux - Shell Loop Types
4. The select loop provides an easy way to create a numbered menu. It is useful when you need to ask user to
choose one or more items from a list of choices.
select var in word1 word2 ... wordN Here var is name of a variable and word1 to wordN are
do sequences of characters separated by spaces.
Statement(s) to be executed for every word.
done
5. Each time the loop executes, value of the variable var is set to the next word in the list of words, word1 to
wordN. This loop was introduced in ksh and has been adapted into bash. It is not available in sh.
#!/bin/ksh 6. You can change the prompt displayed by the select loop
select DRINK in tea cofee water juice appe all none by altering the variable PS3 as follows
do $PS3 = "Please make a selection => " ; export PS3
case $DRINK in
$./test.sh $./test.sh
tea|cofee|water|all)
echo "Go to canteen" 1) tea 1) tea
;; 2) cofee 2) cofee
juice|appe) 3) water 3) water
echo "Available at home" 4) juice 4) juice
;; 5) appe
5) appe
none) 6) all
7) none
6) all
break 7) none
;; #? juice
Available at home Please make a selection => juice
*) echo "ERROR: Invalid selection"
;; #? none Available at home
esac $ Please make a selection => none
done $
18
The break and continue Statement
1. The break statement is used to terminate the execution of the entire loop, after completing the
execution of all of the lines of code up to the break statement. It then steps down to the code
following the end of the loop. The break command can also be used to exit from a nested loop
using this format −
break n (Here n specifies the nth enclosing loop to the exit from)
2. The continue statement is similar to break command, except that it causes current iteration of
loop to exit, rather than the entire loop. This statement is useful when an error has occurred but
you want to try to execute next iteration of loop. Like with break statement, an integer argument
can be given to continue command to skip commands from nested loops.
continue n (n specifies the nth enclosing loop to continue from)
#!/bin/bash #!/bin/bash #!/bin/bash
a=0 for var1 in 1 2 3 NUMS="1 2 3 4 5 6 7"
while [ $a -lt 10 ] do for NUM in $NUMS
do for var2 in 0 5 do
echo $a do Q=`expr $NUM % 2`
if [ $a -eq 5 ] if [ $var1 -eq 2 -a $var2 -eq 0 ] if [ $Q -eq 0 ]
then then then
break break 2 echo "Number is an even number!!"
fi else continue
a=`expr $a + 1` echo "$var1 $var2" fi
done fi echo "Found odd number"
done done
done
19
Escape Sequences for use in Echo Command
Sr.No. Escape Description 1. The printing value of the variable is substituted by its
1 \\ backslash value. Same time, "\n" is substituted by a new line −
2 \a alert (BEL) #!/bin/sh
3 \b backspace a=10
4 \c suppress trailing newline echo -e "Value of a is $a \n"
5 \f form feed 2. The -e option enables the interpretation of backslash
6 \n new line escapes.
7 \r carriage return Value of a is 10
8 \t horizontal tab 3. Following is the result without -e option −
9 \v vertical tab Value of a is 10\n
20
Command substitution and Quotes
1. Command substitution is the mechanism by which the shell performs a given
set of commands and then substitutes their output in the place of the
commands.
`command`
2. When performing the command substitution make sure that you use the
backquote, not the single quote character.
#!/bin/bash SN Quoting Description
1 Single All special characters between these quotes
DATE=`date` quote lose their special meaning.
echo "Date is $DATE" 2 Double Most special characters between these quotes
quote lose their special meaning with these
exceptions − $, `, \$, \', \", \\
USERS=`who | wc -l` 3 Backslash Any character immediately following the
echo "Logged in user are $USERS" backslash loses its special meaning.
4 Back Anything in between back quotes would be
UP=`date ; uptime`
quote treated as a command and would be
echo "Uptime is $UP"
executed.
21
Variable Substitution
Sr.No. Form Description
1 ${var} Substitute the value of var.
2 ${var:-word} If var is null or unset, word is substituted for var. The value
of var does not change.
3 ${var:=word} If var is null or unset, var is set to the value of word.
4 ${var:?message} If var is null or unset, message is printed to standard error. This
checks that variables are set correctly.
5 ${var:+word} If var is set, word is substituted for var. Value of var does not change.
[ abc ...] Match any one of the enclosed characters; a hyphen can be used to
specify a range (e.g., a-z, A-Z, 0–9).
[^abc...] Match any character not enclosed as above.
{abc,xxx,...} Expand each comma-separated string inside braces. The strings need
not match actual filenames.
~ Home directory for the current user.
~ name Home directory of user name.
=n The nth entry in the directory stack, counting from zero.
=- The last entry in the directory stack.
Matches anything that pattern does not match. To work
^ pattern correctly, pattern must contain ?, *, or [...], and should not
contain {...} or ~.
23
Redirection Commands
Sr.No. Command Description
1 pgm > file Output of pgm is redirected to file File descriptor 0 is
2 pgm < file Program pgm reads its input from file normally standard
3 pgm >> file Output of pgm is appended to file input (STDIN), 1 is
4 n > file Output from stream with descriptor n redirected to file standard output
5 n >> file Output from stream with descriptor n appended to file (STDOUT), and 2 is
standard error
6 n >& m Merges output from stream n with stream m
output (STDERR).
7 n <& m Merges input from stream n with stream m
8 << tag Standard input comes from here through next tag at the start of line
9 | Takes output from one program, or process, and sends it to another
$ echo line 1 > users $ wc -l < users 1. A here document is used to redirect input into an
$ cat users 2 interactive shell script or program.
line 1 $ command << delimiter
$ document
$wc -l << EOF Delimiter
$ echo line 2 >> users This is a 2. Here the shell interprets the << operator as an
$ cat users simple lookup instruction to read input until it finds a line containing
line 1 program the specified delimiter. All the input lines up to the line
line 2 EOF containing the delimiter are then fed into the standard
$ 3 input of the command.
3. The delimiter tells shell that here document has
completed.
24
Discard the output
1. Sometimes you will need to execute a command, but you don't want the output
displayed on the screen. In such cases, you can discard the output by redirecting
it to the file /dev/null −
$ command > /dev/null
Here command is the name of the command you want to execute. The file
/dev/null is a special file that automatically discards all its input.
2. To discard both output of a command and its error output, use standard
redirection to redirect STDERR to STDOUT −
$ command > /dev/null 2>&1
3. Here 2 represents STDERR and 1 represents STDOUT. You can display a message
on to STDERR by redirecting STDOUT into STDERR as follows −
$ echo message 1>&2
25
Creating Functions
1. To declare a function, simply use the following syntax −
function_name () {
list of commands
}
2. You can define a function that will accept parameters while calling the function. These
parameters would be represented by $1, $2 and so on.
#!/bin/bash #!/bin/bash
# Define your function here # Define your function here
Hello () { Hello () {
echo "Hello World" echo "Hello World $1 $2"
} }
# Invoke your function # Invoke your function
Hello Hello Sanjeev Gupta
Upon execution, you receives Upon execution, you receives
the following output − the following output −
$./test.sh $./test.sh
Hello World Hello World Sanjeev Gupta
26
Returning Values from Functions
1. If you execute an exit command from inside a function, its effect is not only to
terminate execution of function but also shell program that called the function.
2. If you only want to terminate execution of function, then there is way to come out of a
defined function.
3. You can return any value from your function using return command.
return code
#!/bin/bash Upon execution, you receives following result −
# Define your function here
Hello () { $./test.sh
echo "Hello World $1 $2" Hello World Sanjeev Gupta
return 10 Return value is 10
}
27
Nested Functions
1. One of the more interesting features of functions is that they can call themselves and also other
functions. A function that calls itself is known as a recursive function.
2. Following example demonstrates nesting of two functions −
#!/bin/bash Upon execution, you receives following result −
# Calling one function from another
number_one () { This is the first function speaking...
echo "This is the first function speaking..." This is now the second function speaking...
number_two
}
number_two () {
echo "This is now the second function speaking..."
}
28
Function Call from Prompt
1. You can put definitions for commonly used functions inside your .profile. These
definitions will be available whenever you log in and you can use them at the
command prompt.
2. Alternatively, you can group the definitions in a file, say test.sh, and then execute the
file in the current shell by typing −
$. test.sh
3. This has the effect of causing functions defined inside test.sh to be read and defined to
the current shell as follows −
$ number_one
This is the first function speaking...
This is now the second function speaking...
$
4. To remove the definition of a function from the shell, use the unset command with the
f option. This command is also used to remove the definition of a variable to the shell.
$ unset -f function_name
29
Directory Structure
Sr.No. Directory Description
1 / This is the root directory which should contain only the directories needed at the top
level of the file structure
2 /bin This is where the executable files are located. These files are available to all users
3 /dev These are device drivers
4 /etc Supervisor directory commands, configuration files, disk configuration files, valid user
lists, groups, ethernet, hosts, where to send critical messages
5 /lib Contains shared library files and sometimes other kernel-related files
6 /boot Contains files for booting the system
7 /home Contains the home directory for users and other accounts
8 /mnt Used to mount other temporary file systems, such as cdrom and floppy for the CD-
ROM drive and floppy diskette drive, respectively
9 /proc Contains all processes marked as a file by process number or other information that is
dynamic to the system
10 /tmp Holds temporary files used between system boots
11 /usr Used for miscellaneous purposes, and can be used by many users. Includes
administrative commands, shared files, library files, and others
12 /var Typically contains variable-length files such as log and print files and any other type of
file that may contain a variable amount of data
13 /sbin Contains binary (executable) files, usually for system administration. For
example, fdisk and ifconfig utlities
14 /kernel Contains kernel files
30
Managing Users and Groups
1. There are four main user administration files −
i. /etc/passwd − Keeps the user account and password information. This file holds the
majority of information about accounts on the Unix system.
ii. /etc/shadow − Holds the encrypted password of the corresponding account. Not all the
systems support this file.
iii. /etc/group − This file contains the group information for each account.
iv. /etc/gshadow − This file contains secure group account information.
2. The following table lists out commands that are available on majority of Unix systems to create
and manage accounts and groups −
Sr.No. Command Description
1 useradd Adds accounts to the system
2 usermod Modifies account attributes
3 userdel Deletes accounts from the system
4 groupadd Adds groups to the system
5 groupmod Modifies group attributes
6 groupdel Removes groups from the system
31
System Shutdown
Sr.No. Command Description
1 halt Brings the system down immediately
2 init 0 Powers off the system using predefined scripts to synchronize and
clean up the system prior to shutting down
3 init 6 Reboots the system by shutting it down completely and then
restarting it
4 poweroff Shuts down the system by powering off
5 reboot Reboots the system
6 shutdown Shuts down the system
32
The .profile File
1. 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.
2. 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.
3. You can check your .profile available in your home directory.
33
Listing Running Processes
1. It is easy to see your own processes by running the ps (process status) command as follows −
$ps
PID TTY TIME CMD
18358 ttyp3 00:00:00 sh
18789 ttyp3 00:00:00 ps
2. One of the most commonly used flags for ps is the -f ( f for full) option
Sr.No. Column Description
1 UID User ID that this process belongs to (the person running it)
2 PID Process ID
3 PPID Parent process ID (the ID of the process that started it)
4 C CPU utilization of process
5 STIME Process start time
6 TTY Terminal type associated with the process
7 TIME CPU time taken by the process
8 CMD The command that started this process
34
Special Command-Line Characters
1. Sequential Commands: You can put several commands on the same line by separating them with a ;
(Semicolon) :
$ Is -i flank; mv flank right; Is -i right
3910 flank
3910 right
2. Background Process: Terminating a command with an ampersand (&) causes it to run in background
mode.
❑ Normally, the shell wails until the child process produced by a command dies. Thus you can't
issue a new command until the preceding one finishes.
❑ When a job is run in background, however, process is launched and control returns to your
shell immediately.
❑ Your background job becomes one of the many processes sitting around waiting for its portion
of time sharing. Meanwhile, you can use your terminal to start other activities.
❑ For example, you might wish to check the spelling in a big file:
$ spell warandpeace > wap. spell &
4562
3. Command Grouping: We can use () (Parentheses) to group commands.
(date; cat results) > datres
This sends the output of date followed by the output of cat to the file datres.
❑ If we had used
date; cat results > datres
❑ the result would have been the same as using
date
cat results datres
35
Demystifying && and ||
1. The two conditional operators && and ||, provides for the execution of a command on the
condition that some other command has succeeded or failed.
❑ In a command like
grep Aida slaves && echo "Save Aida!“
the command following the && is performed only if the exit status is 0. that is only if the
string Aida were found in the file slaves.
36
Debug and Troubleshoot Bash Scripts
1. Set the set -x option: One of the most useful techniques for debugging Bash scripts is to set the
set -x option at the beginning of the script. This option enables debugging mode, which causes
Bash to print each command that it executes to the terminal, preceded by a + sign. This can be
incredibly helpful in identifying where errors are occurring in your script.
#!/bin/bash
set -x
# Your script goes here
2. Check the exit code: When Bash encounters an error, it sets an exit code that indicates the nature
of the error. You can check the exit code of the most recent command using the $? variable. A
value of 0 indicates success, while any other value indicates an error.
3. Use echo statements: Another useful technique for debugging Bash scripts is to insert echo
statements throughout your code. This can help you identify where errors are occurring and what
values are being passed to variables.
4. Use the set -e option: If you want your script to exit immediately when any command in the script
fails, you can use the set -e option. This option will cause Bash to exit with an error if any
command in the script fails, making it easier to identify and fix errors in your script.
#!/bin/bash
set -e
# Your script goes here
5. Troubleshooting crons by verifying logs: We can troubleshoot crons using the log files. Logs are
maintained for all the scheduled jobs. You can check and verify in logs if a specific job ran as
intended or not. For Ubuntu/Debian, you can find cronlogs at:
/var/log/syslog
37
PROCESS MAKE-IN-INDIA
RE-ENGINEERING
CAPACITY BUILDING
DIGITAL LOCKER
AURANGABAD