Introduction
Shell scripting can be defined as a group of commands
executed in sequence. Let's start by describing the steps
needed to write and execute a shell script:
Step 1: Open the file using an
editor (e.g., "vi" or "pico".)
vi Firstshellscript.sh
Step 2: All shell scripts should
begin with "#!/bin/bash" or whatever other shell you
prefer. This line is called the shebang, and although it
looks like a comment, it's not: it notifies the shell of
the interpreter to be used for the script. The provided
path must be an absolute one (you can't just use "bash",
for example), and the shebang must be located on the first
line of the script without any preceding space.
Step 3: Write the code that you
want to develop. Our first shell script will be the usual
"Hello World" routine, which we'll place in a file called
'Firstshellscript.sh'.
#!/bin/sh
echo "Hello World"
Step 4:The next step is to make
the script executable by using the "chmod" command.
chmod 744 Firstshellscript.sh
or
chmod +x Firstshellscript.sh
Step 5: Execute the script. This
can be done by entering the name of the script on the
command line, preceded by its path. If it's in the current
directory, this is very simple:
bash$ ./Firstshellscript.sh
Hello World
If you want to see the execution step-by-step - which
is very useful for troubleshooting - then execute it with
the '-x' ('expand arguments') option:
sh -x Firstshellscript.sh
+ echo 'Hello World'
Hello World
Category:
Shell scripting
Shell scripting can be defined as a group of
commands executed in sequence. |
To see the contents of a script, you can use the 'cat'
command or simply open the script in any text editor:
bash$ cat Firstshellscript.sh
#!/bin/sh
echo Hello World
Comments in a Shell
In shell scripting, all lines beginning with # are
comments.
# This is a comment line.
# This is another comment line.
You can also have comments that span multiple lines by
using a colon and single quotes:
: 'This is a comment line.
Again, this is a comment line.
My God, this is yet another comment line.'
Note: This will not work if there is a single quote
mark within the quoted contents.
Variables
As you may or may not know, variables are the most
significant part of any programming language, be it Perl,
C, or shell scripting. In the shell, variables are
classified as either system variables or user-defined
variables.
System Variables
System variables are defined and kept in the
environment of the parent shell (the shell from
which your script is launched.) They are also called
environment variables. These variable names consist of
capital letters, and can be seen by executing the 'set'
command. Examples of system variables are PWD, HOME, USER,
etc. The values of these system variables can be displayed
individually by "echo"ing the system variables. E.g.,
echo $HOME will display the value stored in
the system variable HOME.
When setting a system variable, be sure to use the
"export" command to make it available to the child
shells (any shells that are spawned from the current
one, including scripts):
bash$ SCRIPT_PATH=/home/blessen/shellscript
bash$ export SCRIPT_PATH
Modern shells also allow doing all this in one pass:
bash$ export SCRIPT_PATH=/home/blessen/shellscript
User-Defined Variables
These are the variables that are normally used in
scripting - ones that you don't want or need to make
available to other programs. Their names cannot start with
numbers, and are written using lower case letters and
underscores by convention - e.g. 'define_tempval'.
When we assign a value to a variable, we write the
variable name followed by '=' which is immediately
followed by the value, e.g.,
define_tempval=blessen
(note that there must not be any spaces around the equals
sign.) Now, to use or display the value in
define_tempval, we have to use the
echo
command and precede the variable name with a '$' sign,
i.e.:
bash$ echo $define_tempval
blessen
The following script sets a variable named "username"
and displays its content when executed.
#!/bin/sh
username=blessen
echo "The username is $username"
Commandline Arguments
These are variables that contain the arguments to a
script when it is run. These variables are accessed using
$1, $2, ... $n, where $1 is the first command-line
argument, $2 the second, etc. Arguments are delimited by
spaces. $0 is the name of the script. The variable $# will
display the number of command-line arguments supplied;
this number is limited to 9 arguments in the older shells,
and is practically unlimited in the modern ones.
Consider a script that will take two command-line
arguments and display them. We'll call it 'commandline.sh':
#!/bin/sh
echo "The first variable is $1"
echo "The second variable is $2"
When I execute 'commandline.sh' with command-line
arguments like "blessen" and "lijoe", the output looks
like this:
bash$ ./commandline.sh blessen lijoe
The first variable is blessen
The second variable is lijoe
Exit status variable
This variable tells us if the last command executed was
successful or not. It is represented by $?. A value of 0
means that the command was successful. Any other number
means that the command was unsuccessful (although a few
programs such as 'mail' use a non-zero return to indicate
status rather than failure.) Thus, it is very useful in
scripting.
To test this, create a file named "test", by running
touch test . Then, "display" the content of
the file:
bash$ cat test
Then, check the value of $?.
bash$ echo $?
0
The value is zero because
the command was successful. Now try running 'cat' on a
file that isn't there:
bash$ cat xyz1
bash$ echo $?
1
The value 1 shows that the above command was
unsuccessful.
Scope of a Variable
I am sure most programmers have learned (and probably
worked with) variables and the concept of
scope
(that is, a definition of where a variable has meaning.)
In shell programming, we also use the scope of a variable
for various programming tasks - although this is very
rarely necessary, it can be a useful tool. In the shell,
there are two types of scope: global and local. Local
variables are defined by using a "local" tag preceding the
variable name when it is defined; all other variables,
except for those associated with function arguments, are
global, and thus accessible from anywhere within the
script. The script below demonstrates the differing scopes
of a local variable and a global one:
#!/bin/sh
display()
{
local local_var=100
global_var=blessen
echo "local variable is $local_var"
echo "global variable is $global_var"
}
echo "======================"
display
echo "=======outside ========"
echo "local variable outside function is $local_var"
echo "global variable outside function is $global_var"
Running the above produces the following output:
======================
local variable is 100
global variable is blessen
=======outside ========
local variable outside function is
global variable outside function is blessen
Note the absence of any value for the local variable
outside the function.
Input and Output in Shell Scripting
For accepting input from the keyboard, we use
read. This command will read values typed from the
keyboard, and assign each to the variable specified for
it.
read <variable_name>
For output, we use the
echo command.
echo "statement to be displayed"
Arithmetic Operations in Shell Scripting
Like other scripting languages, shell scripting also
allows us to use arithmetic operations such as addition,
subtraction, multiplication, and division. To use these,
one uses a function called
expr; e.g., "expr
a + b" means 'add a and b'.
e.g.:
sum=`expr 12 + 20`
Similar syntax can be used for subtraction, division,
and multiplication. There is another way to handle
arithmetic operations; enclose the variables and the
equation inside a square-bracket expression starting with
a "$" sign. The syntax is
$[expression operation statement]
e.g.:
echo $[12 + 10]
[ Note that this syntax is not
universal; e.g., it will fail in the Korn shell. The
'$((...))' syntax is more shell-agnostic; better yet, on
the general principle of "let the shell do what it does
best and leave the rest to the standard toolkit", use a
calculator program such as 'bc' or 'dc' and command
substitution. Also, note that shell arithmetic is
integer-only, while the above two methods have no such
problem. -- Ben ]
Conditional Statements
Let's have some fun with a conditional statement like
"if condition". Most of the time, we shell programmers
have situations where we have to compare two variables,
and then execute certain statements depending on the truth
or falsity of the condition. So, in such cases, we have to
use an "if" statement. The syntax is show below:
if [ conditional statement ]
then
... Any commands/statements ...
fi
The script cited below will prompt for a username, and
if the user name is "blessen", will display a message
showing that I have successfully logged in. Otherwise it
will display the message "wrong username".
#!/bin/sh
echo "Enter your username:"
read username
if [ "$username" = "blessen" ]
then
echo 'Success!!! You are now logged in.'
else
echo 'Sorry, wrong username.'
fi
Remember to always enclose the variable being tested in
double quotes; not doing so will cause your script to fail
due to incorrect syntax when the variable is empty. Also,
the square brackets (which are an alias for the 'test'
command) must have a space following the opening bracket
and preceding the closing one.
Variable Comparison
In shell scripting we can perform variable comparison.
If the values of variables to be compared are numerical,
then you have to use these options:
-eq Equal to
-ne Not Equal to
-lt Less than
-le Less than or equal to
-gt Greater than
-ge Greater then or equal to
If they are strings, then you have to use these
options:
= Equal to
!= Not Equal to
< First string sorts before second
> First string sorts after second
Loops
The "for" Loop
The most commonly used loop is the "for" loop. In shell
scripting, there are two types: one that is similar to C's
"for" loop, and an iterator (list processing) loop.
Syntax for the first type of "for" loop (again, this
type is only available in modern shells):
for ((initialization; condition; increment/decrement))
do
...statements...
done
Example:
#!/bin/sh
for (( i=1; $i <= 10; i++ ))
do
echo $i
done
This will produce a list of numbers from 1 to 10. The
syntax for the second, more widely-available, type of
"for" loop is:
for <variable> in <list>
do
...statements...
done
This script will read the contents of '/etc/group' and
display each line, one at a time:
#!/bin/sh
count=0
for i in `cat /etc/group`
do
count=`expr "$count" + 1`
echo "Line $count is being displayed"
echo $i
done
echo "End of file"
Another example of the "for" loop uses "seq" to
generate a sequence:
#!/bin/sh
for i in `seq 1 5`
do
echo $i
done
While Loop
The "while" loop is another useful loop used in all
programming languages; it will continue to execute until
the condition specified becomes false.
while [ condition ]
do
...statement...
done
The following script assigns the value "1" to the
variable num and adds one to the value of
num each time it goes around the loop, as
long as the value of
num is less than 5.
#!/bin/sh
num=1
while [$num -lt 5]; do num=$[$num + 1]; echo $num; done
Category:
Programming
[Break] code into small chunks called
functions, and call them by name in the main
program. This approach helps in debugging, code
re-usability, etc. |
Select and Case Statement
Similar to the "switch/case" construct in C
programming, the combination of "select" and "case"
provides shell programmers with the same features. The
"select" statement is not part of the "case" statement,
but I've put the two of them together to illustrate how
both can be used in programming.
Syntax of select:
select <variable> in <list>
do
...statements...
done
Syntax of case:
case $<variable> in
<option1>) statements ;;
<option2>) statements ;;
*) echo "Sorry, wrong option" ;;
esac
The example below will explain the usage of select and
case together, and display options involving a machine's
services needing to be restarted. When the user selects a
particular option, the script starts the corresponding
service.
#!/bin/bash
echo "***********************"
select opt in apache named sendmail
do
case $opt in
apache) /etc/rc.d/init.d/httpd restart;;
named) /etc/rc.d/init.d/named restart;;
sendmail) /etc/rc.d/init.d/sendmail restart;;
*) echo "Nothing will be restarted"
esac
echo "***********************"
# If this break is not here, then we won't get a shell prompt.
break
done
[ Rather than using an explicit
'break' statement - which is not useful if you want to
execute more than one of the presented options - it is
much better to include 'Quit' as the last option in the
select list, along with a matching case statement. -- Ben
]
Functions
In the modern world where all programmers use the OOP
model for programming, even we shell programmers aren't
far behind. We too can break our code into small chunks
called functions, and call them by name in the main
program. This approach helps in debugging, code
re-usability, etc.
Syntax for "function" is:
<name of function> ()
{ # start of function
statements
} # end of function
Functions are invoked by citing their names in the main
program, optionally followed by arguments. For example:
#!/bin/sh
sumcalc ()
{
sum=$[$1 + $2]
}
echo "Enter the first number:"
read num1
echo "Enter the second number:"
read num2
sumcalc $num1 $num2
echo "Output from function sumcalc: $sum"
Debugging Shell Scripts
Now and then, we need to debug our programs. To do so,
we use the '-x' and '-v' options of the shell. The '-v'
option produces verbose output. The '-x' option will
expand each simple command, "for" command, "case" command,
"select" command, or arithmetic "for" command, displaying
the expanded value of PS4, followed by the command and its
expanded arguments or associated word list. Try them in
that order - they can be very helpful when you can't
figure out the location of a problem in your script.
By
Blessen Cherian ,
Member of Eecutive team,
Poornam Info Vision Pvt Ltd
Bobcares.com, Poornam.com, Blessen.com
|