linuxnewbie.org.gif
Tuesday, 12-Dec-2000 10:40:35 EST
Newbized Help Files articles discussion board bookshelf sensei's log advertising info

-CONTINUED

If you find that you are uncomfortable with the format of the if and test structure, that is:

if test -f /etc/foo
then

then, you can do it like this:

if [ -f /etc/foo ]; then

The square brackets form test. If you have experience in C programming, this syntax might be more comfortable. Notice that there has to be white space surrounding both square brackets. The semicolon: ";" tells the shell that this is the end of the command. Anything after the semicolon will be run as though it is on a separate line. This makes it easier to read basically, and is of course, optional. If you prefer, just put then on the next line.

When using variables with test, it is a good idea to have them surrounded with quotation marks. Example:

if [ "$name" -eq 5 ]; then

while ... do ... done
The while structure is a looping structure. Basically what it does is, "while this condition is true, do this until the condition is no longer true". Let us look at an example:

#!/bin/bash
while true; do
   echo "Press CTRL-C to quit."
done


true is actually a program. What this program does is continuously loop over and over without stopping. Using true is considered to be slow because your shell program has to call it up first and then run it. You can use an alternative, the ":" command:

#!/bin/bash
while :; do
   echo "Press CTRL-C to quit."
done


This achieves the exact same thing, but is faster because it is a built in feature in bash. The only difference is you sacrifice readability for speed. Use whichever one you feel more comfortable with. Here is perhaps, a much more useful example, using variables:

#!/bin/bash
x=0;     # initialize x to 0
while [ "$x" -le 10 ]; do
    echo "Current value of x: $x"
    # increment the value of x:
    x=$(expr $x + 1)
    sleep 1
done

As you can see, we are making use of the test (in its square bracket form) here to check the condition of the variable x. The option -le checks to see if x is less than, or equal to the value 10. In English, the code above says, "While x is less than 10 or equal to 10, print the current value of x, and then add 1 to the current value of x.". sleep 1 is just to get the program to pause for one second. You can remove it if you want. As you can see, what we were doing here was testing for equality. Check if a variable equals a certain value, and if it does, act accordingly. Here is a list of equality tests:

Checks equality between numbers:
x -eq y   Check is x is equals to y
x -ne y   Check if x is not equals to y
x -gt y   Check ifx is greater than y
x -lt y   Check if x is less than y

Checks equality between strings:
x = y   Check if x is the same as y
x != y   Check if x is not the same as y
-n x   Evaluates to true if x is not null
-z x   Evaluates to true if x is null.

The above looping script we wrote should not be hard to understand, except maybe for this line:

x=$(expr $x + 1)

The comment above it tells us that it increments x by 1. But what does $(...) mean? Is it a variable? No. In fact, it is a way of telling the shell that you want to run the command expr $x + 1, and assign its result to x. Any command enclosed in $(...) will be run:

#!/bin/bash
me=$(whoami)
echo "I am $me."


Try it and you will understand what I mean. The above code could have been written as follows with equivalent results:

#!/bin/bash
echo "I am $(whoami)."

You decide which one is easier for you to read. There is another way to run commands or to give variables the result of a command. This will be explained later on. For now, use $(...).

until ... do ... done
The until structure is very similar to the while structure. The only difference is that the condition is reversed. The while structure loops while the condition is true. The until structure loops until the condition is true. So basically it is "until this condition is true, do this". Here is an example:

#!/bin/bash
x=0
until [ "$x" -ge 10 ]; then
    echo "Current value of x: $x"
    x=$(expr $x + 1)
    sleep 1
done

This piece of code may look familiar. Try it out and see what it does. Basically, until will continue looping until x is either greater than, or equal to 10. When it reaches the value 10, the loop will stop. Therefore, the last value printed for x will be 9.

for ... in ... do ... done
The for structure is used when you are looping through a range of variables. For instance, you can write up a small program that prints 10 dots each second:

#!/bin/bash
echo -n "Checking system for errors"
for dots in 1 2 3 4 5 6 7 8 9 10; do
    echo -n "."
    echo "System clean."
done

In case you do not know, the -n option to echo prevents a new line from automatically being added. Try it once with the -n option, and then once without to see what I mean. The variable dots loops through values 1 to 10, and prints a dot at each value. Try this example to see what I mean by the variable looping through the values:

#!/bin/bash
for x in paper pencil pen; do
    echo "The value of variable x is: $x"
    sleep 1
done

When you run the program, you see that x will first hold the value paper, and then it will go to the next value, pencil, and then to the next value, pen. When it finds no more values, the loop ends.

Here is a much more useful example. The following program adds a .html extension to all files in the current directory:

#!/bin/bash
for file in *; do
    echo "Adding .html extension to $file..."
    mv $file $file.html
    sleep 1
done


If you do not know, * is a wild card character. It means, "everything in the current directory", which is in this case, all the files in the current directory. All files in the current directory are then given a .html extension. Recall that variable file will loop through all the values, in this case, the files in the current directory. mv is then used to rename the value of variable file with a .html extension.

case ... in ... done
The case structure is very similar to the if structure. Basically it is great for times where there are a lot of conditions to be checked, and you do not want to have to use if over and over again. Take the following piece of code:

#!/bin/bash
x=5     # initialize x to 5
# now check the value of x:
case $x in
   0) echo "Value of x is 0."
      ;;
   5) echo "Value of x is 5."
      ;;
   9) echo "Value of x is 9."
      ;;
   *) echo "Unrecognized value."
esac

The case structure will check check the value of x against 3 possibilities. In this case, it will first check if x has the value of 0, and then check if the value is 5, and then check if the value is 9. Finally, if all the checks fail, it will produce a message, "Unrecognized value.". Remember that "*" means "everything", and in this case, "any other value other than what was specified". If x holds any other value other than 0, 5, or 9, then this value falls into the *'s category. When using case, each condition must be ended with two semicolons. Why bother using case when you can use if? Here is the equivalent program, written with if. See which one is faster to write, and easier to read:

#!/bin/bash
x=5     # initialize x to 5
if [ "$x" -eq 0 ]; then
    echo "Value of x is 0."
elif [ "$x" -eq 5 ]; then
    echo "Value of x is 5."
elif [ "$x" -eq 9 ]; then
    echo "Value of x is 9."
else
    echo "Unrecognized value."
fi

QUOTATIONS
Quotation marks play a big part in shell scripting. There are three types of quotation marks. They are the double quote: ", the forward quote: ', and the back quote: `. Does each of them mean something? Yes.

The double quote is used mainly to hold a string of words and preserve whitespace. For instance, "This string contains whitespace.". A string enclosed in double quotes is treated as one argument. For instance, take the following examples:

xconsole$ mkdir hello world
xconsole$
ls -F
hello/     world/

Here we created two directories. mkdir took the strings hello and world as two arguments, and thus created two directories. Now, what happens when you do this:

xconsole$ mkdir "hello world"
xconsole$
ls -F
hello/     hello world/     world/

It created a directory with two words. The quotation marks made two words, into one argument. Without the quotation marks, mkdir would think that hello was the first argument, and world, the second.

Forward quotes are used primarily to deal with variables. If a variable is enclosed in double quotes, its value will be evaluated. If it is enclosed in forward quotes, its value will not be evaluated. To make this clearer, try the following example:

#!/bin/bash
x=5     # initialize x to 5
# use double quotes
echo "Using double quotes, the value of x is: $x"
# use forward quotes
echo 'Using forward quotes, the value of x is: $x'


See the difference? You can use double quotes if you do not plan on using variables for the string you wish to enclose. In case you are wondering, yes, forward quotes can be used to preserve whitespace just like double quotes:

xconsole$ mkdir 'hello world'
xconsole$
ls -F
hello world/

Back quotes are completely different from double and forward quotes. They are not used to preserve whitespace. If you recall, earlier on, we used this line:

x=$(expr $x + 1)

As you already know, the result of the command expr $x + 1 is assigned to variable x. The exact same result can be achieved with back quotes:

x=`expr $x + 1`

Which one should you use? Whichever one you prefer. You will find the back quote used more often than the $(...). However, I find $(...) easier to read, especially if you have something like this:

$!/bin/bash
echo "I am `whoami`"

 

[-NHF Control Panel-]
The Linux Channel at internet.com
Linux Planet
Linux Today
Linux Central
Linuxnewbie.org
PHPBuilder
Just Linux
Linux Programming
Linux Start
BSD Today
Apache Today
Enterprise Linux Today
BSD Central
All Linux Devices
SITE DESCRIPTIONS
[-What's New-]
Order a Linuxnewbie T-Shirt
Easy Webcam NHF
Directory Navigation NHF
Installing Snort 1.6.3 on SuSE 6.x-7.x
Customizing vim
The SysVinit NHF
Installing ALSA for the VT82C686 integrated sound
USB Creative Video Blaster II for Linux
Configuring the Intellimouse Explorer in XFree86 V4+
The beginnings of a distro NHF
Getting Past Carnivore?
Getting and Installing PGP
Getting your ATI Rage 128 Working
How to create a multiple partition system
Using Fdisk
Introduction to Programming in C/C++ with Vim
Adding a Hard drive in Linux -- In five steps
Installing ALSA for the Yamaha DS-XG Sound Card
Getting your Diamond Rio Mp3 Player to work with Linux
Bash Programming Cheat Sheet
Installing NVIDIA Drivers for Mandrake
Setting up Portsentry
Hard Drive Speed Tweak for Linux
Sensei's Log
Chat room
Join: Linuxnewbie.org SETI Black Belts!
Send in your news
Click the image to add Linuxnewbie.org to your MyNetscape Page
[-LNO Newsletter-]

[-Archive-]
The beginnings of a distro NHF
Connecting to the Internet using KPPP
Getting your SBLive to work
Unreal Tournament NHF
LWE Day 2 Pictures
LWE Day 1 Pictures
The LNO FAQ!
WoW (Words of Wisdom)
Other sites news
What is Linux?
What is Linux? part deux (ups & downs)
Search newsgroups
The List
ALS Report
Feedback Form
jobs.linuxtoday.com.gif
Match: Format: Sort by:
Search:
[-Quick Links-]

Copyright 2000 internet.com Corp. All Rights Reserved. Legal Notices Privacy Policy

internet.com.gif