06 Linux Shell Programming
06 Linux Shell Programming
Programming or Scripting
2
Programming or Scripting
(Contd…)
Difference between programming and scripting languages:
Programming languages are generally a lot more powerful
and a lot faster than scripting languages. Programming
languages generally start from source code and are compiled
into an executable. This executable is not easily ported into
different operating systems.
A scripting language also starts from source code, but is not
compiled into an executable. Rather, an interpreter reads the
instructions in the source file and executes each instruction.
Interpreted programs are generally slower than compiled
programs. The main advantage is that you can easily port the
source file to any operating system. bash is a scripting
language. Other examples of scripting languages are perl,
lisp, and tcl.
3
Example of a bash program
We must know how to use a text editor. There are two major text
editors in Linux:
vi, emacs (or xemacs)
So fire up a text editor; for example:
bash$ vi
and type the following inside it:
#!/bin/bash
echo “Hello World”
The first line tells Linux to use the bash interpreter to run this script.
We call it hello.sh. Then, make the script executable:
bash$ chmod +x hello.sh
bash$ ./hello.sh
Hello World
The source command
4
Variables
We can use variables as in any programming languages. Their
values are always stored as strings, but there are mathematical
operators in the shell language that will convert variables to
numbers for calculations.
We have no need to declare a variable, just assigning a value to its
reference will create it.
Example:
#!/bin/bash
STR=“Hello World!”
echo $STR
Line 2 creates a variable called STR and assigns the string "Hello
World!" to it. Then the value of this variable is retrieved by putting
the '$' in at the beginning.
5
Warnings!!!
The shell programming language does not type-cast its variables.
This means that a variable can hold number data or character
data.
count=0
count=Sunday
Switching the TYPE of a variable can lead to confusion for the
writer of the script or someone trying to modify it, so it is
recommended to use a variable for only a single TYPE of data in a
script.
\ is the bash escape character and it preserves the literal value of
the next character that follows.
bash$: ls \*
ls: *: No such file or directory
6
The export command
The export command puts a variable into the environment so it will be
accessible to child processes. For instance:
x=hello
bash # Run a child shell.
echo $x # Nothing in x.
exit # Return to parent.
export x
bash
echo $x
hello # It is there.
If the child modifies x, it will not modify the parent’s original value. Verify this
by changing x in the following way:
x=ciao
exit
echo $x
hello
7
Environmental Variables
There are two types of variables:
Local variables
Environmental variables
Environmental variables are set by the system and can usually be
found by using the env command. Environmental variables hold
special values. For instance,
bash$: echo $SHELL
/bin/bash
bash$: echo $PATH
/usr/X11R6/bin:/usr/local/bin:/bin:/usr/bin
Environmental variables are defined in /etc/profile, /etc/profile.d/ and
~/.bashrc. These files are the initialization files and they are read
when bash shell is invoked. When a login shell exits, bash reads
~/.bash_logout
8
Environmental Variables
(Contd…)
HOME: The default argument (home directory) for cd.
PATH: The search path for commands. It is a colon-separated list of
directories that are searched when you type a command.
Usually, we type in the commands in the following way:
bash$ ./executable
By setting PATH=$PATH:. our working directory is included in the search
path for commands, and we simply type:
bash$ executable
If we type in:
bash$ mkdir ~/bin
and we include the following lines in the ~/.bashrc:
PATH=$PATH:$HOME/bin
export PATH
we obtain that the directory /home/baba/bin is included in the search path
for commands/executables
9
Environmental Variables
(Contd…)
LOGNAME: contains the user name
HOSTNAME: contains the computer/host name
PS1: sequence of characters shown before the prompt
\t hour
\d date
\w current directory
\W last part of the current directory
\u user name
\$ prompt character
Example:
[guest@homelinux guest]$ PS1=‘ciao \u *’
ciao baba * _
10
The read command
The read command allows you to prompt for input and
store it in a variable
Example:
#!/bin/bash
echo -n “Enter name of file to delete: ”
read file
echo “Type 'y' to remove it, 'n' to change
your mind ... ”
rm -i $file
echo "That was YOUR decision baby!!!“
11
Arithmetic Evaluation
The let statement can be used to do mathematical functions:
bash$: let X=10+2*7
bash$: echo $X
24
bash$: let Y=X+2*4
bash$: echo $Y
32
An arithmetic expression can be evaluated by $[expression] or $
((expression))
bash$: echo “$((123+20))”
143
bash$: VALORE=$[123+20]
bash$: echo “$[123*$VALORE]”
17589
12
Arithmetic Evaluation
(Contd…)
Available operators: +, -, /, *, %
Example:
#! /bin/bash
echo -n “Enter the first number: ” ; read x
echo -n “Enter the second number: ”; read y
add=$(($x + $y))
sub=$(($x - $y))
mul=$(($x * $y))
div=$(($x / $y))
mod=$(($x % $y))
# print out the answers:
echo “Sum: $add”
echo “Difference: $sub”
echo “Product: $mul”
echo “Quotient: $div”
echo “Remainder: $mod”
13
Conditional Statements
Conditionals let us decide whether to perform an action or not. This
decision is taken by evaluating an expression. The most basic form
is:
if [expression];
then
statements
elif [expression];
then
statements
else
statements
fi
the elif (else if) and else sections are optional
14
The test command
15
Expressions
An expression can be: String comparison, Numeric comparison, File
operators and Logical operators
String Comparisons:
= compare if two strings are equal
!= compare if two strings are not equal
-n evaluate if string length is greater than zero
-z evaluate if string length is equal to zero
Examples:
[ s1 = s2 ] (true if s1 same as s2, else false)
[ s1 != s2 ] (true if s1 not same as s2, else false)
[ s1 ] (true if s1 is not empty, else false)
[ -n s1 ] (true if s1 has a length greater then 0, else false)
[ -z s2 ] (true if s2 has a length of 0, otherwise false)
16
Expressions
(Contd…)
Number Comparisons:
-eq compare if two numbers are equal
-ge compare if one number is greater than or equal to a number
-le compare if one number is less than or equal to a number
-ne compare if two numbers are not equal
-gt compare if one number is greater than another number
-lt compare if one number is less than another number
Examples:
[ n1 -eq n2 ] (true if n1 same as n2, else false)
[ n1 -ge n2 ] (true if n1greater then or equal to n2, else false)
[ n1 -le n2 ] (true if n1 less then or equal to n2, else false)
[ n1 -ne n2 ] (true if n1 is not same as n2, else false)
[ n1 -gt n2 ] (true if n1 greater then n2, else false)
[ n1 -lt n2 ] (true if n1 less then n2, else false)
17
Example of test command
clear
echo
echo –n “Enter a number: “
read num
if test $num -eq 0
then
echo “The number entered by you is zero”
elif test $num -lt 0
then
echo “The number entered by you is negative”
else
echo “The number entered by you is positive”
fi
18
Without the test command
19
Example (without using test)
clear
echo
echo -n "Enter a number: "
read num
if [ $num -eq 0 ]
then
echo "The number entered by you is zero"
elif [ $num -lt 0 ]
then
echo "The number entered by you is negative"
else
echo "The number entered by you is positive"
fi
20
Some more examples
#!/bin/bash
echo -n “Enter your login name: "
read name
if [ “$name” = “$USER” ];
then
echo “Hello, $name. How are you today?”
else
echo “You are not $USER. Who are you?”
fi
21
Some more examples
#!/bin/bash
echo -n “Enter a number 1 < x < 10: "
read num
if [ “$num” -lt 10 ]; then
if [ “$num” -gt 1 ]; then
echo “$num*$num=$(($num*$num))”
else
echo “Wrong insertion!”
fi
else
echo “Wrong insertion!”
fi
22
Some more examples
#!/bin/bash
clear
echo
echo -n "Enter two names: "
read name1 name2
if [ $name1 = $name2 ]
then
echo "The names entered by you are the same"
else
echo "The names are different"
fi
23
Expressions
(Contd…)
Files operators:
-d check if path given is a directory
-f check if path given is a file
-e check if file name exists
-r check if read permission is set for file or
directory
-s check if a file has a length greater than 0
-w check if write permission is set for a file or
directory
-x check if execute permission is set for a file or
directory
24
Expressions
(Contd…)
Examples:
[ -d fname ] (true if fname is a directory, otherwise false)
[ -f fname ] (true if fname is a file, otherwise false)
[ -e fname ] (true if fname exists, otherwise false)
[ -s fname ] (true if fname length is greater then 0, else
false)
[ -r fname ] (true if fname has the read permission, else
false)
[ -w fname ] (true if fname has the write permission, else
false)
[ -x fname ] (true if fname has the execute permission, else
false)
25
Example
#!/bin/bash
if [ -f /etc/passwd ];
then
cp /etc/passwd .
cp /etc/passwd /tmp/pass
echo “Done.”
else
echo “This file does not exist.”
exit 1
fi
26
Exercise
Exercise: Write a shell script which accepts a
file name:
The script checks if file exists
If file exists, copy the file to the same name
+ .bak (if the .bak file already exists, ask if you
want to replace it).
When done, you should have the original file
and one with a .bak at the end.
27
Expressions
(Contd…)
Logical operators:
! negate (NOT) a logical expression
-a logically AND two logical expressions
-o logically OR two logical expressions
28
Example
#!/bin/bash
echo -n “Enter a number 1 < x < 10:”
read num
if [ “$num” -gt 1 –a “$num” -lt 10 ];
then
echo “$num*$num=$(($num*$num))”
else
echo “Wrong insertion !”
fi
29
Expressions
(Contd…)
Logical operators:
&& logically AND two logical expressions
|| logically OR two logical expressions
30
Expressions
(Contd…)
#!/bin/bash
echo -n "Enter a number 1 < x < 10: "
read num
if [ “$num” -gt 1 ] && [ “$num” -lt 10 ];
then
echo “$num*$num=$(($num*$num))”
else
echo “Wrong insertion !”
fi
31
Strange Example!!!
#!/bin/bash
echo “Enter a path: ”; read x
if cd $x; then
echo “I am in $x and it contains”; ls
else
echo “The directory $x does not
exist”;
exit 1
fi
32
case Statement
Used to execute statements based on specific values. Often used in place of
an if statement if there are a large number of conditions.
Value used can be an expression
each set of statements must be ended by a pair of semicolons;
a *) is used to accept any value not matched with list of values
case $var in
val1)
statements;;
val2)
statements;;
*)
statements;;
esac
33
Example
#!/bin/bash
echo -n “Enter a number 1 < x < 10: ”
read x
case $x in
1) echo “Value of x is 1.”;;
2) echo “Value of x is 2.”;;
3) echo “Value of x is 3.”;;
4) echo “Value of x is 4.”;;
5) echo “Value of x is 5.”;;
6) echo “Value of x is 6.”;;
7) echo “Value of x is 7.”;;
8) echo “Value of x is 8.”;;
9) echo “Value of x is 9.”;;
0 | 10) echo “wrong number.”;;
*) echo “Unrecognized value.”;;
esac
34
Iteration Statements
The for structure is used when you are
looping through a range of variables.
for var in list
do
statements
done
35
Examples
statements are executed with var set to each value in the
list
#!/bin/bash
let sum=0
for num in 1 2 3 4 5
do
let “sum = $sum + $num”
done
echo $sum
36
Examples
(Contd…)
#!/bin/bash
let sum=0
for num in $*
do
let “sum = $sum + $num”
done
echo $sum
37
Assignment
Write a shell script to find the sum of n
natural numbers:
1)Prompt the user to enter a
positive value of n using the
read command
2)Enter the value of n using
command-line arguments
Take care of all possible error conditions
and generate appropriate error messages
38
Some more examples
#!/bin/bash
for x in paper pencil pen; do
echo “The value of variable x is: $x”
sleep 1
done
39
Some more examples
(Contd…)
If the list part is left off, var is set to each parameter passed to the
script ($1, $2, $3,…)
#!/bin/bash
for x
do
echo “The value of variable x is: $x”
sleep 1
done
OUTPUT:
./file.sh alpha beta
The value of variable x is: alpha
The value of variable x is: beta
40
What does this script do?
#!/bin/bash
# Move the command line arg files to old directory.
if [ $# -eq 0 ] #check for command line arguments
then
echo “Usage: $0 file …”
exit 1
fi
if [ ! –d “$HOME/old” ]
then
mkdir “$HOME/old”
fi
echo The following files will be saved in the old directory:
echo $*
for p in $* #loop through all command line arguments
do
mv $p “$HOME/old/”
chmod 400 “$HOME/old/$p”
done
ls -l “$HOME/old”
41
Using Arrays with Loops
In the bash shell, we may use arrays. The simplest way
to create one is using one of the two subscripts:
pet[0]=dog
pet[1]=cat
pet[2]=fish
pet=(dog cat fish)
We may have up to 1024 elements. To extract a value,
type ${arrayname[i]}
echo ${pet[0]}
dog
42
Using Arrays with Loops
(Contd…)
To extract all the elements, use an asterisk as:
echo ${arraynames[*]}
We can combine arrays with loops using a for
loop:
for x in ${arrayname[*]}
do
...
done
43
Debugging
Bash provides two options which will give
useful information for debugging
-x : displays each line of the script with variable
substitution and before execution
-v : displays each line of the script as typed
before execution
44
Debugging
(Contd…)
Usage: #!/bin/bash –v, or #!/bin/bash –x , or #!/bin/bash –xv
#!/bin/bash –x
echo –n “Enter a number: ”; read x
let sum=0
for (( i=1 ; $i<$x ; i=$i+1 )) ; do
let “sum = $sum + $i”
done
echo “the sum of the first $x numbers is: $sum”
45
Debugging
bash$: ./test.sh (Contd…)
+ echo –n ‘Enter a number: ’
Enter a number: + read x
3
+ let sum=0
+ (( i=0 ))
+ (( 0<=3 ))
+ let ‘sum = 0 + 0’
+ (( i=0+1 ))
+ (( 1<=3 ))
+ let ‘sum = 0 + 1’
+ (( i=1+1 ))
+ (( 2<=3 ))
+ let ‘sum = 1 + 2’
+ (( i=2+1 ))
+ (( 3<=3 ))
+ let ‘sum = 3 + 3’
+ (( i=3+1 ))
+ (( 4<=3 ))
+ echo ‘the sum of the first 3 numbers is: 6’
the sum of the first 3 numbers is: 6
46
while statement
The while structure is a looping structure. Used
to execute a set of commands while a specified
condition is true. The loop terminates as soon as
the condition becomes false. If condition never
becomes false, loop will never exit.
while expression
do
statements
done
47
while statement
(Contd…)
#!/bin/bash
echo –n “Enter a number: ”; read x
let sum=0; let i=1
while [ $(($i)) –le $x ]; do
let “sum = $sum + $i”
i=$i+1
done
echo “the sum of the first $x numbers is: $sum”
48
Example
#!/bin/bash
clear ; loop=y
while [ “$loop” = y ] ; do
echo “Menu”; echo “====”
echo “D: print the date”
echo “W: print the users who are currently log on.”
echo “P: print working directory”
echo “Q: quit.”
echo
read –s choice
case $choice in
D | d) date ;;
W | w) who ;;
P | p) pwd ;;
Q | q) loop=n ;;
*) echo “Illegal choice.” ;;
esac
echo
done
49
The continue statement
50
The continue statement
(Contd…)
#!/bin/bash
LIMIT=19
echo
echo “Printing Numbers 1 through 20 (but not 3 and 11)”
a=0
while [ $a -le “$LIMIT” ]; do
a=$(($a+1))
if [ “$a” -eq 3 ] || [ “$a” -eq 11 ]
then
continue
fi
echo -n “$a ”
done
51
The break statement
The break command terminates the loop (breaks out of it).
#!/bin/bash
LIMIT=19
echo
echo “Printing Numbers 1 through 20, but something happens after 2…”
a=0
while [ $a -le “$LIMIT” ]; do
a=$(($a+1))
if [ “$a” -gt 2 ]
then
break
fi
echo -n “$a ”
done
echo; echo; echo
exit 0
52
The until statement
The until structure is very similar to the
while structure. Except for a minor
difference _________________.
until [expression]
do
statements
done
53
The until statement
(Contd…)
#!/bin/bash
echo “Enter a number: ”; read x
echo ; echo Count Down
until [ “$x” -le 0 ]; do
echo $x
x=$(($x – 1))
sleep 1
done
echo ; echo DONE!!!
54
Manipulating Strings
Bash supports a surprising number of string manipulation operations.
Unfortunately, these tools lack a unified focus.
${#string} gives the string length
${string:position} extracts sub-string from $string at $position
${string:position:length} Extracts $length characters of sub-
string from $string at $position
Example
bash$: st=0123456789
bash$: echo ${#st}
10
bash$: echo ${st:6}
6789
bash$: echo ${st:6:2}
67
55
Functions
Functions make scripts easier to maintain. Basically it breaks
up the program into smaller pieces. A function performs an
action defined by you, and it can return a value if you wish.
#!/bin/bash
hello()
{
echo “You are in function hello()”
}
echo “Calling function hello()…”
hello
echo “You are now out of function hello()”
56
What does this script do?
(Contd…)
#!/bin/bash
function check() {
if [ -e “$PWD/$1" ]
then
return 0
else
return 1
fi
}
58
Shell Keywords
59