Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Variables are "words" that hold a value. The shell enables you to create, assign, and
delete variables.
Syntax: name=value
$ FRUIT=peach
defines the variable FRUIT and assigns it the value peach. Variables of this type are
called scalar 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 ( _). In addition, a variable's name can start only with a letter or an
underscore.
Values
$ FRUIT=peach
$ FRUIT=2apples
$ FRUIT=apple+pear+kiwi
Accessing Values
To access the value stored in a variable, prefix its name with the dollar sign ( $). For
example, the command
$ echo $FRUIT
Peach
Array Variables
The Bourne shell, sh, supports only scalar variables, which are the type of variables you
have seen so far. The Korn shell, ksh, extends this to include array variables.
The simplest method of creating an array variable is to assign a value to one of its
indices. This is expressed as follows:
Syntax: name[index]=value
Here 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.
As an example, the following commands
$ FRUIT[0]=apple
$ FRUIT[1]=banana
$ FRUIT[2]=orange
We set the array indices in sequence, but this is not necessary. For example, if you issue
the command
$ FRUIT[10]=plum
the value of the item at index 10 in the array FRUIT is set to plum. One thing to note here
is that the shell does not create a bunch of blank array items to fill the space between
index 2 and index 10. Instead, it keeps track of only those array indices that contain
values.
Caution - In ksh, numerical indices for arrays must be between 0 and 1,023
The second form of array initialization is used to set multiple elements at once. In ksh,
this is done as
follows:
or
Syntax: ${name[index]}
$ echo ${FRUIT[2]}
For all
${name[*]}
${name[@]}
$ echo ${FRUIT[*]}
If any of the array items hold values with spaces, this form of array access will not work
and will need to use the second form. The second form quotes all the array entries so that
embedded spaces are preserved.
For example, define the following array item:
$ FRUIT[3]="passion fruit"
Assuming that FRUIT is defined as given previously, accessing the entire array using the
following
Command $ echo ${FRUIT[*]}
Commands accessing FRUIT using this form of array access get five values, with passion
and fruit treated as separate items.
To get only four items, you have to use the following form:
$ echo ${FRUIT[@]}
The output from this command looks similar to the previous commands:
apple banana orange passion fruit
but the commands see only four items because the shell quotes the last item as passion
fruit.
Read-only Variables
The 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.
$ FRUIT=kiwi
$ readonly FRUIT
$ echo $FRUIT
kiwi
$ FRUIT=cantaloupe
The last command results in an error message:
Unsetting Variables
Unsetting a variable tells the shell to remove the variable from the list of variables that it
tracks.
This is like asking the shell to forget a piece of information because it is no longer
required.
Both scalar and array variables are unset using the unset command:
$ unset FRUIT
unsets the variable FRUIT.
You cannot use the unset command to unset variables that are marked readonly.
Filename substitution is the process by which the shell expands a string containing
wildcards into a list of filenames.
$ ls *
lists every file and the contents of every directory in the current directory. If there are any
invisible files or directories, they are not listed.
$ ls ch1*
matches all the files and directories in the current directory that start with the letters ch1.
$ ls *.doc
matches all the files and directories in the current directory that end with .doc
Matching Suffixes and Prefixes
You can match both the suffix and the prefix of files using the * character as follows:
Here, command is the name of a command, such as ls, prefix is the filename prefix, and
suffix is the filename suffix you want to match. For example, the command
$ ls Backup*.doc
matches all the files in the current directory that start with the letters Backup and end with
.doc
$ ls C*st*j
matches all the files in the current directory that start with the letter C and end with j
containing characters st.
$ ls ch0?.doc
list all files that have names of the form ch0X.doc, where X is a single number or letter.
Fortunately, the shell provides you with the capability to match sets of characters
Here command is the name of a command, such as ls, and characters represents the
characters you want to match. For example, the following command fulfills the previous
requirements:
$ ls ch0[0123456789].doc
$ ls ch0[0-9].doc
Try
$ ls [a-z]*
$ ls [a-zA-Z]*
$ ls *[a-zA-Z0-9]
$ ls a[bs]*
$ ls a?c
Negating a Set
Consider a situation where you need a list of all files except those that contain the letter a.
You have two approaches to solving this problem:
If you choose the first approach, you need to construct a set of all the characters that your
filename can contain. You can start with: [b-zA-Z0-9]. This set does not include the
special characters that are allowed in filenames. Attempting to include all these characters
creates a huge set that requires complicated quoting. An approximation of this set is [b-
zA-Z0-9\-_\+\=\\\'\"\{\[\}\]
Compared to this, the second approach is much better because you only need to specify
the list of characters that you don't want.
The [ wildcard provides you the capability to match all characters except those that are
specified as the set. This is called negating the set, which you can accomplish by
specifying the ! operator as the first character in a set.
Here, command is the name of a command, such as ls, and characters is the set of
characters that you do not want to be matched. For example, to list all files except those
that start with the letter a, you can use the command
$ ls [!a]*
Reading a value
Using expr
$ a=`expr 5+7`
$b=`expr $a+8`
Echo $b
Flow Control
The if statement
The case statement
if list1
then
list2
elif list3
then
list4
else
list5
fi
Both the elif and the else statements are optional. An if statement can be written with any
number of elif statements.
Because the shell considers an if statement to be a list, you can write it all in one line as
follows:
if [ $FRUIT = apple ]
then
echo "An apple a day keeps the doctor away."
else
echo "You must like doctors, your fruit $FRUIT is not an apple."
fi
capital= Delhi
echo “The capital of India is: \c”
read cap
if [ -z $cap ]
then
echo ”string cannot be blank”
elif [ $cap != $capital ]
then
echo “You have made a mistake”
fi
Numeric Tests
Using AND/OR/NOT
! binary not operator ! expr
-a binary and operator expr1 –a expr2
-o binary or operator expr1 -o expr2
Using Test
The test command is used to check for conditions other than the success or failure of an
operation. The command succeeds or fails, based on whether the condition is true or
false.
Testing files
if test -d $1
then
echo "$1 is a directory"
else
if [ -f $1 ]
then
more $1
fi
fi
To check whether a file does not meet a specified condition, use ! as not.
if [ ! –r $1]
then
echo “File cannot be read”
fi
Case Construct
case word in
pattern1)
list1
;;
pattern2)
list2
;;
esac
Here the string word is compared against every pattern until a match is found. The list
following the matching pattern executes. If no matches are found, the case statement
exits without performing any action. There is no maximum number of patterns, but the
minimum is one.
When a list executes, the command ;; indicates that program flow should jump to the end
of the entire case statement. This is similar to break in the C programming language.
case word in
pattern1) list1 ;;
pattern2) list2 ;;
esac
This form should be used only if the list of commands to be executed is short.
FRUIT=kiwi
case $FRUIT in
apple) echo "Apple pie is quite tasty." ;;
banana) echo "I like banana nut bread." ;;
kiwi) echo "New Zealand is famous for kiwi." ;;
esac
Using Patterns
In the previous example, you used fixed strings as the pattern. If used in this fashion the
case statement degenerates into an if statement. For example, the if statement
is more verbose, but the real power of the case statement does not lie in simplifying if
statements. The power lies in the fact that it uses patterns to perform matching.
A pattern is a string that consists of regular characters and special wildcard characters.
The pattern determines whether a match is present.
FRUIT=kiwi
case $FRUIT in
apple) echo "Apple pie is quite tasty." ;;
banana) echo "I like banana nut bread." ;;
kiwi) echo "New Zealand is famous for kiwi." ;;
*) echo “no comments”;;
Esac
var=$1
case $var in
[0-9] | [a-z]*) echo "valid";;
*) echo "invalid"
esac
LOOPING
The while loop enables you to execute a set of commands repeatedly until some
condition occurs. It is usually used when you need to manipulate the value of a variable
repeatedly.
The for loop enables you to execute a set of commands repeatedly for each item in a list.
One of its most common uses is in performing the same set of commands for a large
number of files.
Syntax:
while command
do
list
done
Here command is a single command to execute, whereas list is a set of one or more
commands to execute. Although command can be any valid UNIX command, it is usually
a test expression
1. Execute command.
2. If the exit status of command is nonzero, exit from the while loop.
3. If the exit status of command is zero, execute list.
4. When list finishes executing, return to Step 1.
If both command and list are short, the while loop is written in a single line as follows:
i=1
while [ $i -le 10 ]
do
echo $i
i=` expr $i + 1 `
done
There are no restrictions on how deeply nested loops can be, but you should try to avoid
nesting loops more deeply than four or five levels to avoid difficulties in finding and
fixing problems in your script.
i=1
while [ $i -le 10 ]
do
y=$i
while [ $y -ge 0 ]
do
echo "$y \c"
y=` expr $y - 1 `
done
echo
i=` expr $i + 1 `
done
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.
The until operator executes the commands within the loop as long as the test condition is
false.
until command
do
list
done
Here command is a single command to execute, whereas list is a set of one or more
commands to execute. Although command can be any valid UNIX command, it is usually
a test expression.
If both command and list are short, the until loop can be written on a single line as
follows:
In most cases the until loop is identical to a while loop with list1 negated using the !
operator. For example, the following while loop
i=1
while [ ! $i -le 10 ]
do
echo $i
i=` expr $i + 1 `
done
i=1;
until [ $i -ge 10 ]
do
echo $i
i=` expr $i + 1 `
done
The for Loop
Here name is the name of a variable and word1 to wordN are sequences of characters
separated by spaces (words). Each time the for loop executes, the value of the variable
name is set to the next word in the list of words, word1 to wordN. The first time, name is
set to word1; the second time, it's set to word2; and so on.
This means that the number of times a for loop executes depends on the number of words
that are specified.
You can also write the entire loop on a single line as follows:
If list and the number of words are short, the single line form is often chosen; otherwise,
the multiple-line form is preferred.
Note that although the output is identical to the while loop, the for loop does something
altogether different. In each iteration, $i is set to the next item in the list. When the list is
finished, the loop exits.
If you change the list slightly, notice how the output changes:
for i in 0 1 2 4 3 5 8 7 9
do
echo $i
done
do
cat $i
done
Here name is the name of a variable and word1 to wordN are sequences of characters
separated by spaces (words). The set of commands to execute after the user has made a
selection is specified by list.
The execution process for a select loop is as follows:
The menu presented by the select loop looks like the following:
1) add
2) subtract
3) multiply
4) divide
5) quit
#?
Loop Control
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
a=0
while [ $a -lt 10 ]
do
echo $a
if [ $a -eq 5 ]
then
break
fi
a=`expr $a + 1`
done
0
1
2
3
4
5
The continue statement is similar to the break command, except that it causes the current
iteration of the loop to exit, rather than the entire loop.
The following loop makes use of continue statement which returns from the continue
statement and start processing next statement:
for NUM in 1 2 3 4 5 6 7
do
Q=`expr $NUM % 2`
if [ $Q -eq 0 ]
then
echo "Number is an even number!!"
continue
fi
echo "Found odd number"
done