@WikiNewPageEditViewToolsHelp
Create New Page Create New Page from Copy
Create your new wiki
Edit this page Copy from this page Rename
Attach (Upload) File
Edit Menu
Newest Change History Referer Trackback
Page List Tag Cloud RSS1.0 RSS2.0
Search
@Wiki Guide
FAQ/about @wiki FAQ/about Editting FAQ/about Register
Update Infomation Release Plan

BOURNE SHELL

Added line is this color

Deleted line is this color

 
 <h3 style="margin: auto 0in"><font face="Times New Roman">BOURNE SHELL
 PROGRAMMING</font></h3>
 <h3 style="margin: auto 0in"></h3>
 <h3 style="margin: auto 0in"><font face="Times New Roman">Purpose Of This
 Tutorial</font></h3>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">This tutorial is written to help people understand some of the basics
 of shell script programming, and hopefully to introduce some of the
 possibilities of simple but powerful programming available under the bourne
 shell. As such, it has been written as a basis for one-on-one or group
 tutorials and exercises, and as a reference for subsequent use.</font></p>
 <h3 style="margin: auto 0in"><font face="Times New Roman">Getting The Most
 Recent Version Of This Tutorial</font></h3>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">The most recent version of this tutorial is available from:</font>
 <a href="http://steve-parker.org/sh/sh.shtml"><font face="Times New Roman"
 size="3">http://steve-parker.org/sh/sh.shtml</font></a><font face=
 "Times New Roman" size="3">. Always check there for the latest copy.</font></p>
 <h3 style="margin: auto 0in"><font face="Times New Roman">A Brief History of
 sh</font></h3>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Steve Bourne, wrote the Bourne shell which appeared in the Seventh
 Edition Bell Labs Research version of Unix.<br>
 Many other shells have been written; this particular tutorial concentrates on
 the Bourne and the Bourne Again shells.<br>
 Other shells include the Korn Shell (ksh), the C Shell (csh), and variations
 such as tcsh.<br>
 This tutorial does <em>not</em> cover those shells. Maybe a future version will
 cover ksh; I do not intend to write a tutorial for csh, as</font> <a href=
 "http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/"><font face=
 "Times New Roman" size="3">csh programming is considered
 harmful</font></a><font face="Times New Roman" size="3">.</font></p>
 <h3 style="margin: auto 0in"><font face="Times New Roman">Audience</font></h3>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">This tutorial assumes some prior experience; namely:</font></p>
 <ul type="disc">
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l9 level1 lfo1">
 <font face="Times New Roman" size="3">Use of an interactive Unix
 shell</font></li>
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l9 level1 lfo1">
 <font face="Times New Roman" size="3">Minimal programming knowledge - use of
 variables, functions, is useful background knowledge</font></li>
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l9 level1 lfo1">
 <font face="Times New Roman" size="3">Understanding of how Unix commands are
 structured, and competence in using some of the more common ones.</font></li>
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l9 level1 lfo1">
 <font face="Times New Roman" size="3">Programmers of C, Pascal, or any
 programming language who can maybe read shell scripts, but don't feel they
 understand exactly how they work.</font></li>
 </ul>
 <h3 style="margin: auto 0in"><font face="Times New Roman">Typographical
 Conventions Used in This Tutorial</font></h3>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Significant words will be written in <em>italics</em> when mentioned
 for the first time.</font></p>
 <p><font face="Times New Roman" size="3">Code segments and script output will
 be displayed as preformatted text.<br>
 Command-line entries will be preceded by the Dollar sign ($). If your prompt is
 different, enter the command:</font></p>
 <pre>
 <font size="2">PS1="$ " ; export PS1</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Then your interactions should match the examples given (such as $
 ./my-script.sh below).<br>
 Script output (such as "Hello World" below) is displayed at the start of the
 line.</font></p>
 <pre>
 <font size="2">$ echo '#!/bin/sh' &gt; my-script.sh</font>
 </pre>
 <pre>
 <font size="2">$ echo 'echo Hello World' &gt;&gt; my-script.sh</font>
 </pre>
 <pre>
 <font size="2">$ chmod 755 my-script.sh</font>
 </pre>
 <pre>
 <font size="2">$ ./my-script.sh</font>
 </pre>
 <pre>
 <font size="2">Hello World</font>
 </pre>
 <pre>
 <font size="2">$</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Entire scripts will be surrounded by thick horizontal rules and
 include a reference where available to the plain text of the script:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/first.sh.txt"><font face="Times New Roman" size=
 "3">first.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2"># This is a comment!</font>
 </pre>
 <pre>
 <font size="2">echo Hello World<span style=
 "mso-tab-count: 1">    </span># This is a comment, too!</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Note that to make a file executable, you must set the eXecutable bit,
 and for a shell script, the Readable bit must also be set:</font></p>
 <pre>
 <font size="2">$ chmod a+rx first.sh</font>
 </pre>
 <table class="MsoNormalTable" style="width: 100%; mso-cellspacing: 1.5pt"
 cellpadding="0" width="100%" border="0">
 <tbody>
 <tr style="mso-yfti-irow: 0; mso-yfti-lastrow: yes">
 <td style=
 "border-right: #ece9d8; padding-right: 0.75pt; border-top: #ece9d8; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #ece9d8; padding-top: 0.75pt; border-bottom: #ece9d8; background-color: transparent">
 <p class="MsoNormal" style="margin: 0in 0in 0pt"></p>
 </td>
 <td style=
 "border-right: #ece9d8; padding-right: 0.75pt; border-top: #ece9d8; padding-left: 0.75pt; padding-bottom: 0.75pt; border-left: #ece9d8; padding-top: 0.75pt; border-bottom: #ece9d8; background-color: transparent">
 <p class="MsoNormal" style="margin: 0in 0in 0pt; text-align: right" align=
 "right"></p>
 </td>
 </tr>
 </tbody>
 </table>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Shell script programming has a bit of a bad press amongst some Unix
 systems administrators. This is normally because of one of two
 things:</font></p>
 <ul type="disc">
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l8 level1 lfo2">
 <font face="Times New Roman" size="3">The speed at which an interpreted program
 will run as compared to a C program, or even an interpreted Perl
 program.</font></li>
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l8 level1 lfo2">
 <font face="Times New Roman" size="3">Since it is easy to write a simple
 batch-job type shell script, there are a lot of poor quality shell scripts
 around.</font></li>
 </ul>
 <p><font face="Times New Roman" size="3">It is partly due to this that there is
 a certain machismo associated with creating <em>good</em> shell scripts.
 Scripts which can be used as CGI programs, for example, without losing out too
 much in speed to Perl (though both would lose to C, in many cases, were speed
 the only criteria).<br>
 There are a number of factors which can go into good, clean, quick, shell
 scripts.</font></p>
 <ul type="disc">
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l6 level1 lfo3">
 <font face="Times New Roman" size="3">The most important criteria must be a
 clear, readable layout.</font></li>
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l6 level1 lfo3">
 <font face="Times New Roman" size="3">Second is avoiding unnecessary
 commands.</font></li>
 </ul>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">A clear layout makes the difference between a shell script appearing
 as "black magic" and one which is easily maintained and understood.<br>
 You may be forgiven for thinking that with a simple script, this is not too
 significant a problem, but two things here are worth bearing in
 mind.</font></p>
 <ol type="1">
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l4 level1 lfo4">
 <font face="Times New Roman" size="3">First, a simple script will, more often
 than anticipated, grow into a large, complex one.</font></li>
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l4 level1 lfo4">
 <font face="Times New Roman" size="3">Secondly, if nobody else can understand
 how it works, you will be lumbered with maintaining it yourself for the rest of
 your life!</font></li>
 </ol>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Something about shell scripts seems to make them particularly likely
 to be badly indented, and since the main control structures are if/then/else
 and loops, indentation is critical for understanding what a script
 does.</font></p>
 <p><font face="Times New Roman" size="3">One of the major weaknesses in many
 shell scripts is lines such as:</font></p>
 <pre>
 <font size="2">cat /tmp/myfile | grep "mystring"</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">which would run much faster as:</font></p>
 <pre>
 <font size="2">grep "mystring" /tmp/myfile</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Not much, you may consider; the OS has to load up the</font>
 <code><span style="font-size: 10pt">/bin/grep</span></code> <font face=
 "Times New Roman" size="3">executable, which is a reasonably small 75600 bytes
 on my system, open a</font> <code><span style=
 "font-size: 10pt">pipe</span></code> <font face="Times New Roman" size="3">in
 memory for the transfer, load and run the</font> <code><span style=
 "font-size: 10pt">/bin/cat</span></code> <font face="Times New Roman" size=
 "3">executable, which is an even smaller 9528 bytes on my system, attach it to
 the input of the pipe, and let it run.<br>
 Of course, this kind of thing is what the OS is there for, and it's normally
 pretty efficient at doing it. But if this command were in a loop being run many
 times over, the saving of not locating and loading the</font>
 <code><span style="font-size: 10pt">cat</span></code> <font face=
 "Times New Roman" size="3">executable, setting up and releasing the pipe, can
 make some difference, especially in, say, a CGI environment where there are
 enough other factors to slow things down without the script itself being too
 much of a hurdle. Some Unices are more efficient than others at what they call
 "building up and tearing down processes" - ie, loading them up, executing them,
 and clearing them away again. But however good your flavour of Unix is at doing
 this, it'd rather not have to do it at all.</font></p>
 <p><font face="Times New Roman" size="3">As a result of this, you may hear
 mention of the Useless Use of Cat Award (UUoC), also known in some circles as
 <strong>The Award For The Most Gratuitous Use Of The Word Cat In A Serious
 Shell Script</strong> being bandied about on the</font> <code><span style=
 "font-size: 10pt">comp.unix.shell</span></code> <font face="Times New Roman"
 size="3">newsgroup from time to time. This is purely a way of peers keeping
 each other in check, and making sure that things are done right.</font></p>
 <p><font face="Times New Roman" size="3">Speaking of which, I would like to
 recommend the</font> <code><span style=
 "font-size: 10pt">comp.os.unix.shell</span></code> <font face="Times New Roman"
 size="3">newsgroup to you, although its signal to noise ratio seems to have
 decreased in recent years. There are still some real gurus who hang out there
 with good advice for those of us who need to know more (and that's all of us!).
 Sharing experiences is the key to all of this - the reason behind this tutorial
 itself, and we can all learn from and contribute to open discussions about such
 issues.<br>
 Which leads me nicely on to something else: Don't <em>ever</em> feel too close
 to your own shell scripts; by their nature, the source cannot be closed. If you
 supply a customer with a shell script, s/he can inspect it quite easily. So you
 might as well accept that it will be inspected by anyone you pass it to; use
 this to your advantage with the</font> <a href=
 "http://www.gnu.org/copyleft/gpl.html"><font face="Times New Roman" size=
 "3">GPL</font></a> <font face="Times New Roman" size="3">- encourage people to
 give you feedback and bugfixes for free!</font></p>
 <h2 style="margin: 12pt 0in 3pt"><em>First Script</em></h2>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">For our first shell script, we'll just write a script which says
 "Hello World". We will then try to get more out of a Hello World program than
 any other tutorial you've ever read :-)<br>
 Create a file (first.sh) as follows:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/first.sh.txt"><font face="Times New Roman" size=
 "3">first.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2"># This is a comment!</font>
 </pre>
 <pre>
 <font size="2">echo Hello World<span style=
 "mso-tab-count: 1">    </span># This is a comment, too!</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">The first line tells Unix that the file is to be executed by /bin/sh.
 This is the standard location of the Bourne shell on just about every Unix
 system. If you're using GNU/Linux, /bin/sh is normally a symbolic link to
 bash.</font></p>
 <p><font face="Times New Roman" size="3">The second line begins with a special
 symbol:</font> <code><span style="font-size: 10pt">#</span></code><font face=
 "Times New Roman" size="3">. This marks the line as a comment, and it is
 ignored completely by the shell.<br>
 The only exception is when the <em>very first</em> line of the file starts
 with</font> <code><span style="font-size: 10pt">#!</span></code> <font face=
 "Times New Roman" size="3">- as ours does. This is a special directive which
 Unix treats specially. It means that even if you are using csh, ksh, or
 anything else as your interactive shell, that what follows should be
 interpreted by the Bourne shell.<br>
 Similarly, a Perl script may start with the line</font> <code><span style=
 "font-size: 10pt">#!/usr/bin/perl</span></code> <font face="Times New Roman"
 size="3">to tell your interactive shell that the program which follows should
 be executed by perl. For Bourne shell programming, we shall stick to</font>
 <code><span style="font-size: 10pt">#!/bin/sh.</span></code></p>
 <p><font face="Times New Roman" size="3">The third line runs a command:</font>
 <code><span style="font-size: 10pt">echo</span></code><font face=
 "Times New Roman" size="3">, with two parameters, or arguments - the first is
 "Hello"; the second is "World".<br>
 Note that echo will automatically put a single space between its
 parameters.<br>
 The</font> <code><span style="font-size: 10pt">#</span></code> <font face=
 "Times New Roman" size="3">symbol still marks a comment; the # and anything
 following it is ignored by the shell.</font></p>
 <p><font face="Times New Roman" size="3">now run</font> <code><span style=
 "font-size: 10pt">chmod 755 first.sh</span></code> <font face="Times New Roman"
 size="3">to make the text file executable, and run</font> <code><span style=
 "font-size: 10pt">./first.sh</span></code><font face="Times New Roman" size=
 "3">.<br>
 Your screen should then look like this:</font></p>
 <pre>
 <font size="2">$ chmod 755 first.sh</font>
 </pre>
 <pre>
 <font size="2">$ ./first.sh</font>
 </pre>
 <pre>
 <font size="2">Hello World</font>
 </pre>
 <pre>
 <font size="2">$</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">You will probably have expected that! You could even just
 run:</font></p>
 <pre>
 <font size="2">$ echo Hello World</font>
 </pre>
 <pre>
 <font size="2">Hello World</font>
 </pre>
 <pre>
 <font size="2">$</font>
 </pre>
 <p><font face="Times New Roman" size="3">Now let's make a few changes.<br>
 First, note that</font> <code><span style="font-size: 10pt">echo</span></code>
 <font face="Times New Roman" size="3">puts ONE space between its parameters.
 Put a few spaces between "Hello" and "World". What do you expect the output to
 be? What about putting a TAB character between them?<br>
 As always with shell programming, try it and see.<br>
 The output is exactly the same! We are calling the</font> <code><span style=
 "font-size: 10pt">echo</span></code> <font face="Times New Roman" size=
 "3">program with two arguments; it doesn't care any more than</font>
 <code><span style="font-size: 10pt">cp</span></code> <font face=
 "Times New Roman" size="3">does about the gaps in between them.<br>
 Now modify the code again:</font></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2"># This is a comment!</font>
 </pre>
 <pre>
 <font size="2">echo "Hello<span style=
 "mso-spacerun: yes">    </span>World"<span style=
 "mso-tab-count: 1">     </span><span style=
 "mso-spacerun: yes">    </span># This is a comment, too!</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">This time it works. You probably expected that, too, if you have
 experience of other programming languages. But the key to understanding what is
 going on with more complex command and shell script, is to understand and be
 able to explain: WHY?</font> <code><span style=
 "font-size: 10pt">echo</span></code> <font face="Times New Roman" size="3">has
 now been called with just ONE argument - the string "Hello  World". It
 prints this out exactly.<br>
 The point to understand here is that the shell parses the arguments BEFORE
 passing them on to the program being called. In this case, it strips the quotes
 but passes the string as one argument.<br>
 As a final example, type in the following script. Try to predict the outcome
 before you run it:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/first2.sh.txt"><font face="Times New Roman"
 size="3">first2.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2"># This is a comment!</font>
 </pre>
 <pre>
 <font size="2">echo "Hello<span style=
 "mso-spacerun: yes">    </span>World"<span style=
 "mso-tab-count: 1">     </span><span style=
 "mso-spacerun: yes">    </span># This is a comment, too!</font>
 </pre>
 <pre>
 <font size="2">echo "Hello World"</font>
 </pre>
 <pre>
 <font size="2">echo "Hello * World"</font>
 </pre>
 <pre>
 <font size="2">echo Hello * World</font>
 </pre>
 <pre>
 <font size="2">echo Hello<span style=
 "mso-spacerun: yes">    </span>World</font>
 </pre>
 <pre>
 <font size="2">echo "Hello" World</font>
 </pre>
 <pre>
 <font size="2">echo Hello "<span style=
 "mso-spacerun: yes">   </span>" World</font>
 </pre>
 <pre>
 <font size="2">echo "Hello "*" World"</font>
 </pre>
 <pre>
 <font size="2">echo `hello` world</font>
 </pre>
 <pre>
 <font size="2">echo 'hello' world</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Is everything as you expected? If not, don't worry! These are just
 some of the things we will be covering in this tutorial ... and yes, we will be
 using more powerful commands than</font> <code><span style=
 "font-size: 10pt">echo</span></code><font face="Times New Roman" size=
 "3">!</font></p>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"></p>
 <h2 style="margin: 12pt 0in 3pt"><em>Variables - Part I</em></h2>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Just about every programming language in existence has the concept of
 <em>variables</em> - a symbolic name for a chunk of memory to which we can
 assign values, read and manipulate its contents. The bourne shell is no
 exception, and this section introduces idea. This is taken further in</font>
 <a href="http://steve-parker.org/sh/variables2.shtml"><font face=
 "Times New Roman" size="3">Variables - Part II</font></a> <font face=
 "Times New Roman" size="3">which looks into variables which are set for us by
 the environment.<br>
 Let's look back at our first Hello World example. This could be done using
 variables (though it's such a simple example that it doesn't really warrant
 it!)<br>
 Note that there must be no spaces around the "=" sign:</font>
 <code><span style="font-size: 10pt">VAR=value</span></code> <font face=
 "Times New Roman" size="3">works;</font> <code><span style=
 "font-size: 10pt">VAR = value</span></code> <font face="Times New Roman" size=
 "3">doesn't work. In the first case, the shell sees the "=" symbol and treats
 the command as a variable assignment. In the second case, the shell assumes
 that VAR must be the name of a command and tries to execute it.<br>
 If you think about it, this makes sense - how else could you tell it to run the
 command VAR with its first argument being "=" and its second argument being
 "value"?<br>
 Enter the following code into var1.sh:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/var.sh.txt"><font face="Times New Roman" size=
 "3">var.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">MY_MESSAGE="Hello World"</font>
 </pre>
 <pre>
 <font size="2">echo $MY_MESSAGE</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">This assigns the string "Hello World" to the variable</font>
 <code><span style="font-size: 10pt">MY_MESSAGE</span></code> <font face=
 "Times New Roman" size="3">then</font> <code><span style=
 "font-size: 10pt">echo</span></code><font face="Times New Roman" size="3">es
 out the value of the variable.<br>
 Note that we need the quotes around the string Hello World. Whereas we could
 get away with</font> <code><span style="font-size: 10pt">echo Hello
 World</span></code> <font face="Times New Roman" size="3">because echo will
 take any number of parameters, a variable can only hold one value, so a string
 with spaces must be quoted to that the shell knows to treat it all as one.
 Otherwise, the shell will try to execute the command</font> <code><span style=
 "font-size: 10pt">World</span></code> <font face="Times New Roman" size=
 "3">after assigning</font> <code><span style=
 "font-size: 10pt">MY_MESSAGE=Hello</span></code></p>
 <p><font face="Times New Roman" size="3">The shell does not care about types of
 variables; they may store strings, integers, real numbers - anything you
 like.<br>
 People used to Perl may be quite happy with this; if you've grown up with C,
 Pascal, or worse yet Ada, this may seem quite strange.<br>
 In truth, these are all stored as strings, but routines which expect a number
 can treat them as such.<br>
 If you assign a string to a variable then try to add 1 to it, you will not get
 away with it:</font></p>
 <pre>
 <font size="2">$ x="hello"</font>
 </pre>
 <pre>
 <font size="2">$ y=`expr $x + 1`</font>
 </pre>
 <pre>
 <font size="2">expr: non-numeric argument</font>
 </pre>
 <pre>
 <font size="2">$</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Since the external program</font> <code><span style=
 "font-size: 10pt">expr</span></code> <font face="Times New Roman" size="3">only
 expects numbers. But there is no syntactic difference between:</font></p>
 <pre>
 <font size="2">MY_MESSAGE="Hello World"</font>
 </pre>
 <pre>
 <font size="2">MY_SHORT_MESSAGE=hi</font>
 </pre>
 <pre>
 <font size="2">MY_NUMBER=1</font>
 </pre>
 <pre>
 <font size="2">MY_PI=3.142</font>
 </pre>
 <pre>
 <font size="2">MY_OTHER_PI="3.142"</font>
 </pre>
 <pre>
 <font size="2">MY_MIXED=123abc</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Note though that special characters must be properly escaped to avoid
 interpretation by the shell.<br>
 This is discussed further in</font> <a href=
 "http://steve-parker.org/sh/escape.shtml"><font face="Times New Roman" size=
 "3">Escape Characters</font></a><font face="Times New Roman" size=
 "3">.</font></p>
 <p><font face="Times New Roman" size="3">We can interactively set variable
 names using the</font> <code><span style="font-size: 10pt">read</span></code>
 <font face="Times New Roman" size="3">command; the following script asks you
 for your name then greets you personally:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/var2.sh.txt"><font face="Times New Roman" size=
 "3">var2.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">echo What is your name?</font>
 </pre>
 <pre>
 <font size="2">read MY_NAME</font>
 </pre>
 <pre>
 <font size="2">echo "Hello $MY_NAME - hope you're well."</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Mario Bacinsky kindly pointed out to me that I had originally missed
 out the double-quotes in line 3, which meant that the single-quote in the word
 "you're" was unmatched, causing an error. It is this kind of thing which can
 drive a shell programmer crazy, so watch out for them!</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">This is using the shell-builtin command</font> <code><span style=
 "font-size: 10pt">read</span></code> <font face="Times New Roman" size=
 "3">which reads a line from standard input into the variable supplied.<br>
 Note that even if you give it your full name and don't use double quotes around
 the</font> <code><span style="font-size: 10pt">echo</span></code> <font face=
 "Times New Roman" size="3">command, it still outputs correctly. How is this
 done? With the</font> <code><span style=
 "font-size: 10pt">MY_MESSAGE</span></code> <font face="Times New Roman" size=
 "3">variable earlier we had to put double quotes around it to set it.<br>
 What happens, is that the</font> <code><span style=
 "font-size: 10pt">read</span></code> <font face="Times New Roman" size=
 "3">command automatically places quotes around its input, so that spaces are
 treated correctly. (You will need to quote the output, of course - e.g.</font>
 <code><span style="font-size: 10pt">echo "$MY_MESSAGE"</span></code><font face=
 "Times New Roman" size="3">).</font> <a name="scope"></a></p>
 <h2 style="margin: 12pt 0in 3pt"><em>Scope of Variables</em></h2>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Variables in the bourne shell do not have to be declared, as they do
 in languages like C. But if you try to read an undeclared variable, the result
 is the empty string. You get no warnings or errors. This can cause some subtle
 bugs - if you assign</font> <code><span style=
 "font-size: 10pt">MY_OBFUSCATED_VARIABLE=Hello</span></code> <font face=
 "Times New Roman" size="3">and then</font> <code><span style=
 "font-size: 10pt">echo $MY_OSFUCATED_VARIABLE</span></code><font face=
 "Times New Roman" size="3">, you will get nothing (as the second OBFUSCATED is
 mis-spelled).</font></p>
 <p><font face="Times New Roman" size="3">There is a command called</font>
 <code><span style="font-size: 10pt">export</span></code> <font face=
 "Times New Roman" size="3">which has a fundamental effect on the scope of
 variables. In order to really know what's going on with your variables, you
 will need to understand something about how this is used.</font></p>
 <p><font face="Times New Roman" size="3">Create a small shell script,</font>
 <code><span style="font-size: 10pt">myvar2.sh</span></code><font face=
 "Times New Roman" size="3">:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/myvar2.sh.txt"><font face="Times New Roman"
 size="3">myvar2.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">echo "MYVAR is: $MYVAR"</font>
 </pre>
 <pre>
 <font size="2">MYVAR="hi there"</font>
 </pre>
 <pre>
 <font size="2">echo "MYVAR is: $MYVAR"</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Now run the script:</font></p>
 <pre>
 <font size="2">$ ./myvar2.sh</font>
 </pre>
 <pre>
 <font size="2">MYVAR is:</font>
 </pre>
 <pre>
 <font size="2">MYVAR is: hi there</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">MYVAR hasn't been set to any value, so it's blank. Then we give it a
 value, and it has the expected result.<br>
 Now run:</font></p>
 <pre>
 <font size="2">$ MYVAR=hello</font>
 </pre>
 <pre>
 <font size="2">$ ./myvar2.sh</font>
 </pre>
 <pre>
 <font size="2">MYVAR is:</font>
 </pre>
 <pre>
 <font size="2">MYVAR is: hi there</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">It's still not been set! What's going on?!<br>
 When you call</font> <code><span style=
 "font-size: 10pt">myvar2.sh</span></code> <font face="Times New Roman" size=
 "3">from your interactive shell, a new shell is spawned to run the script. This
 is partly because of the</font> <code><span style=
 "font-size: 10pt">#!/bin/sh</span></code> <font face="Times New Roman" size=
 "3">line at the start of the script, which we discussed</font> <a href=
 "http://steve-parker.org/sh/first.shtml"><font face="Times New Roman" size=
 "3">earlier</font></a><font face="Times New Roman" size="3">.<br>
 We need to</font> <code><span style="font-size: 10pt">export</span></code>
 <font face="Times New Roman" size="3">the variable for it to be inherited by
 another program - including a shell script. Type:</font></p>
 <pre>
 <font size="2">$ export MYVAR</font>
 </pre>
 <pre>
 <font size="2">$ ./myvar2.sh</font>
 </pre>
 <pre>
 <font size="2">MYVAR is: hello</font>
 </pre>
 <pre>
 <font size="2">MYVAR is: hi there</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Now look at line 3 of the script: this is changing the value of</font>
 <code><span style="font-size: 10pt">MYVAR</span></code><font face=
 "Times New Roman" size="3">. But there is no way that this will be passed back
 to your interactive shell. Try reading the value of</font> <code><span style=
 "font-size: 10pt">MYVAR</span></code><font face="Times New Roman" size=
 "3">:</font></p>
 <pre>
 <font size="2">$ echo $MYVAR</font>
 </pre>
 <pre>
 <font size="2">hello</font>
 </pre>
 <pre>
 <font size="2">$</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Once the shell script exits, its environment is destroyed. But</font>
 <code><span style="font-size: 10pt">MYVAR</span></code> <font face=
 "Times New Roman" size="3">keeps its value of</font> <code><span style=
 "font-size: 10pt">hello</span></code> <font face="Times New Roman" size=
 "3">within your interactive shell.<br>
 In order to receive environment changes back from the script, we must
 <em>source</em> the script - this effectively runs the script within our own
 interactive shell, instead of spawning another shell to run it.<br>
 We can source a script via the "." command:</font></p>
 <pre>
 <font size="2">$ MYVAR=hello</font>
 </pre>
 <pre>
 <font size="2">$ echo $MYVAR</font>
 </pre>
 <pre>
 <font size="2">hello</font>
 </pre>
 <pre>
 <font size="2">$ . ./myvar2.sh</font>
 </pre>
 <pre>
 <font size="2">MYVAR is: hello</font>
 </pre>
 <pre>
 <font size="2">MYVAR is: hi there</font>
 </pre>
 <pre>
 <font size="2">$ echo $MYVAR</font>
 </pre>
 <pre>
 <font size="2">hi there</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">The change has now made it out into our shell again! This is how
 your</font> <code><span style="font-size: 10pt">.profile</span></code>
 <font face="Times New Roman" size="3">or</font> <code><span style=
 "font-size: 10pt">.bash_profile</span></code> <font face="Times New Roman"
 size="3">file works, for example.<br>
 Note that in this case, we don't need to</font> <code><span style=
 "font-size: 10pt">export MYVAR</span></code><font face="Times New Roman" size=
 "3">.<br>
 Thanks to <em>sway</em> for pointing out that I'd originally said</font>
 <code><span style="font-size: 10pt">echo MYVAR</span></code> <font face=
 "Times New Roman" size="3">above, not</font> <code><span style=
 "font-size: 10pt">echo $MYVAR</span></code> <font face="Times New Roman" size=
 "3">as it should be.</font></p>
 <p><font face="Times New Roman" size="3">One other thing worth mentioning at
 this point about variables, is to consider the following shell
 script:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">echo "What is your name?"</font>
 </pre>
 <pre>
 <font size="2">read USER_NAME</font>
 </pre>
 <pre>
 <font size="2">echo "Hello $USER_NAME"</font>
 </pre>
 <pre>
 <font size="2">echo "I will create you a file called $USER_NAME_file"</font>
 </pre>
 <pre>
 <font size="2">touch $USER_NAME_file</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Think about what result you would expect. For example, if you enter
 "steve" as your USER_NAME, should the script create</font> <code><span style=
 "font-size: 10pt">steve_file</span></code><font face="Times New Roman" size=
 "3">?<br>
 Actually, no. This will cause an error unless there is a variable called</font>
 <code><span style="font-size: 10pt">USER_NAME_file</span></code><font face=
 "Times New Roman" size="3">. The shell does not know where the variable ends
 and the rest starts. How can we define this?<br>
 The answer is, that we enclose the variable itself in curly
 brackets:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/user.sh.txt"><font face="Times New Roman" size=
 "3">user.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">echo "What is your name?"</font>
 </pre>
 <pre>
 <font size="2">read USER_NAME</font>
 </pre>
 <pre>
 <font size="2">echo "Hello $USER_NAME"</font>
 </pre>
 <pre>
 <font size="2">echo "I will create you a file called ${USER_NAME}_file"</font>
 </pre>
 <pre>
 <font size="2">touch "${USER_NAME}_file"</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">The shell now knows that we are referring to the variable</font>
 <code><span style="font-size: 10pt">USER_NAME</span></code> <font face=
 "Times New Roman" size="3">and that we want it suffixed with</font>
 <code><span style="font-size: 10pt">_file</span></code><font face=
 "Times New Roman" size="3">. This can be the downfall of many a new shell
 script programmer, as the source of the problem can be difficult to track
 down.</font></p>
 <p><font face="Times New Roman" size="3">Also note the quotes around</font>
 <code><span style="font-size: 10pt">"${USER_NAME}_file"</span></code>
 <font face="Times New Roman" size="3">- if the user entered "Steve Parker"
 (note the space) then without the quotes, the arguments passed to</font>
 <code><span style="font-size: 10pt">touch</span></code> <font face=
 "Times New Roman" size="3">would be</font> <code><span style=
 "font-size: 10pt">Steve</span></code> <font face="Times New Roman" size=
 "3">and</font> <code><span style="font-size: 10pt">Parker_file</span></code>
 <font face="Times New Roman" size="3">- that is, we'd effectively be
 saying</font> <code><span style="font-size: 10pt">touch Steve
 Parker_file</span></code><font face="Times New Roman" size="3">, which is two
 files to be</font> <code><span style=
 "font-size: 10pt">touch</span></code><font face="Times New Roman" size="3">ed,
 not one. The quotes avoid this. Thanks to Chris for highlighting
 this.</font></p>
 <h2 style="margin: 12pt 0in 3pt"><em>Wildcards</em></h2>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Wildcards are really nothing new if you have used Unix at all
 before.<br>
 It is not necessarily obvious how they are useful in shell scripts though. This
 section is really just to get the old grey cells thinking how things look when
 you're in a shell script - predicting what the effect of using different
 syntaxes are. This will be used later on, particularly in the</font> <a href=
 "http://steve-parker.org/sh/loops.shtml"><font face="Times New Roman" size=
 "3">Loops</font></a> <font face="Times New Roman" size="3">section.<br>
 Think first how you would copy all the files from</font> <code><span style=
 "font-size: 10pt">/tmp/a</span></code> <font face="Times New Roman" size=
 "3">into</font> <code><span style=
 "font-size: 10pt">/tmp/b</span></code><font face="Times New Roman" size="3">.
 All the .txt files? All the .html files?<br>
 Hopefully you will have come up with:</font></p>
 <pre>
 <font size="2">$ cp /tmp/a/* /tmp/b/</font>
 </pre>
 <pre>
 <font size="2">$ cp /tmp/a/*.txt /tmp/b/</font>
 </pre>
 <pre>
 <font size="2">$ cp /tmp/a/*.html /tmp/b/</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Now how would you list the files in</font> <code><span style=
 "font-size: 10pt">/tmp/a/</span></code> <font face="Times New Roman" size=
 "3">without using</font> <code><span style="font-size: 10pt">ls
 /tmp/a/</span></code><font face="Times New Roman" size="3">?<br>
 How about</font> <code><span style="font-size: 10pt">echo
 /tmp/a/*</span></code><font face="Times New Roman" size="3">? What are the two
 key differences between this and the</font> <code><span style=
 "font-size: 10pt">ls</span></code> <font face="Times New Roman" size=
 "3">output? How can this be useful? Or a hinderance?<br>
 How could you rename all .txt files to .bak? Note that</font></p>
 <pre>
 <font size="2">$ mv *.txt *.bak</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">will not have the desired effect; think about how this gets expanded
 by the shell before it is passed to</font> <code><span style=
 "font-size: 10pt">mv</span></code><font face="Times New Roman" size="3">. Try
 this using</font> <code><span style="font-size: 10pt">echo</span></code>
 <font face="Times New Roman" size="3">instead of</font> <code><span style=
 "font-size: 10pt">mv</span></code> <font face="Times New Roman" size="3">if
 this helps.<br>
 We will look into this further later on, as it uses a few concepts not yet
 covered.</font></p>
 <h2 style="margin: 12pt 0in 3pt"><em>Escape Characters</em></h2>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Certain characters are significant to the shell; we have seen, for
 example, that the use of double quotes (") characters affect how spaces and TAB
 characters are treated, for example:</font></p>
 <pre>
 <font size="2">$ echo Hello<span style=
 "mso-spacerun: yes">    </span>World</font>
 </pre>
 <pre>
 <font size="2">Hello World</font>
 </pre>
 <pre>
 <font size="2">$ echo "Hello<span style=
 "mso-spacerun: yes">    </span>World"</font>
 </pre>
 <pre>
 <font size="2">Hello<span style="mso-spacerun: yes">   </span>World</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">So how do we display:</font> <code><span style=
 "font-size: 10pt">Hello  "World"</span></code> <font face="Times New Roman"
 size="3">?</font></p>
 <pre>
 <font size="2">$ echo "Hello<span style=
 "mso-spacerun: yes">  </span>"World""</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">The first and last " characters wrap the whole lot into one parameter
 passed to</font> <code><span style="font-size: 10pt">echo</span></code>
 <font face="Times New Roman" size="3">so that the spacing between the two words
 is kept as is. But the code:</font></p>
 <pre>
 <font size="2">$ echo "Hello<span style=
 "mso-spacerun: yes">  </span>"World""</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">would be interpreted as three parameters:</font></p>
 <ul type="disc">
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l2 level1 lfo5">
 <font face="Times New Roman" size="3">"Hello  "</font></li>
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l2 level1 lfo5">
 <font face="Times New Roman" size="3">World</font></li>
 <li class="MsoNormal" style=
 "margin: 0in 0in 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in; mso-list: l2 level1 lfo5">
 <font face="Times New Roman" size="3">""</font></li>
 </ul>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">So the output would be</font></p>
 <pre>
 <font size="2">Hello<span style="mso-spacerun: yes">   </span>World</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Note that we lose the quotes entirely. This is because the first and
 second quotes mark off the Hello and following spaces; the second argument is
 an unquoted "World" and the third argument is the empty string; "".</font></p>
 <p><font face="Times New Roman" size="3">Most characters
 (</font><code><span style="font-size: 10pt">*</span></code><font face=
 "Times New Roman" size="3">,</font> <code><span style=
 "font-size: 10pt">'</span></code><font face="Times New Roman" size="3">, etc)
 are not interpreted (ie, they are taken literally) by means of placing them in
 double quotes ("). They are taken as is and passed on the the command being
 called. An example using the asterisk (*) goes:</font></p>
 <pre>
 <font size="2">$ echo *</font>
 </pre>
 <pre>
 <font size="2">case.shtml escape.shtml first.shtml </font>
 </pre>
 <pre>
 <font size="2">functions.shtml hints.shtml index.shtml </font>
 </pre>
 <pre>
 <font size="2">ip-primer.txt raid1+0.txt</font>
 </pre>
 <pre>
 <font size="2">$ echo *txt</font>
 </pre>
 <pre>
 <font size="2">ip-primer.txt raid1+0.txt</font>
 </pre>
 <pre>
 <font size="2">$ echo "*"</font>
 </pre>
 <pre>
 <font size="2">*</font>
 </pre>
 <pre>
 <font size="2">$ echo "*txt"</font>
 </pre>
 <pre>
 <font size="2">*txt</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">In the first example, * is expanded to mean all files in the current
 directory.<br>
 In the second example, *txt means all files ending in</font> <code><span style=
 "font-size: 10pt">txt</span></code><font face="Times New Roman" size="3">.<br>
 In the third, we put the * in double quotes, and it is interpreted
 literally.<br>
 In the fourth example, the same applies, but we have appended</font>
 <code><span style="font-size: 10pt">txt</span></code> <font face=
 "Times New Roman" size="3">to the string.</font></p>
 <p><font face="Times New Roman" size="3">However,</font> <code><span style=
 "font-size: 10pt">", $, `, and</span></code> <font face="Times New Roman" size=
 "3">are still interpreted by the shell, even when they're in double quotes.<br>
 The backslash () character is used to mark these special characters so that
 they are not interpreted by the shell, but passed on to the command being run
 (for example,</font> <code><span style=
 "font-size: 10pt">echo</span></code><font face="Times New Roman" size=
 "3">).<br>
 So to output the string: (Assuming that the value of</font> <code><span style=
 "font-size: 10pt">$X</span></code> <font face="Times New Roman" size="3">is
 5):</font></p>
 <pre>
 <font size="2">A quote is ", backslash is , backtick is `.</font>
 </pre>
 <pre>
 <font size="2">A few spaces are<span style=
 "mso-spacerun: yes">   </span>and dollar is $. $X is 5.</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">we would have to write:</font></p>
 <pre>
 <font size="2">$ echo "A quote is ", backslash is , backtick is `."</font>
 </pre>
 <pre>
 <font size="2">A quote is ", backslash is , backtick is `.</font>
 </pre>
 <pre>
 <font size="2">$ echo "A few spaces are<span style=
 "mso-spacerun: yes">   </span>; dollar is $. $X is ${X}."</font>
 </pre>
 <pre>
 <font size="2">A few spaces are<span style=
 "mso-spacerun: yes">   </span>; dollar is $. $X is 5.</font>
 </pre>
 <p><font face="Times New Roman" size="3">We have seen why the " is special for
 preserving spacing. Dollar is special because it marks a variable, so</font>
 <code><span style="font-size: 10pt">$X</span></code> <font face=
 "Times New Roman" size="3">is replaced by the shell with the contents of the
 variable</font> <code><span style="font-size: 10pt">X</span></code><font face=
 "Times New Roman" size="3">. Backslash is special because it is itself used to
 mark other characters off; we need the following options for a complete
 shell:</font></p>
 <pre>
 <font size="2">$ echo "This is  a backslash"</font>
 </pre>
 <pre>
 <font size="2">This is  a backslash</font>
 </pre>
 <pre>
 <font size="2">$ echo "This is " a quote and this is  a backslash"</font>
 </pre>
 <pre>
 <font size="2">This is " a quote and this is  a backslash</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">So backslash itself must be escaped to show that it is to be taken
 literally. The other special character, the backtick, is discussed later
 in</font> <a href="http://steve-parker.org/sh/external.shtml"><font face=
 "Times New Roman" size="3">External Programs</font></a><font face=
 "Times New Roman" size="3">.</font></p>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"></p>
 <h2 style="margin: 12pt 0in 3pt"><em>Loops</em></h2>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Most languages have the concept of loops: If we want to repeat a task
 twenty times, we don't want to have to type in the code twenty times, with
 maybe a slight change each time.<br>
 As a result, we have</font> <code><span style=
 "font-size: 10pt">for</span></code> <font face="Times New Roman" size=
 "3">and</font> <code><span style="font-size: 10pt">while</span></code>
 <font face="Times New Roman" size="3">loops in the Bourne shell. This is
 somewhat fewer features than other languages, but nobody claimed that shell
 programming has the power of C.</font> <a name="for"></a></p>
 <h3 style="margin: auto 0in"><font face="Times New Roman">For Loops</font></h3>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><code><span style=
 "font-size: 10pt">for</span></code> <font face="Times New Roman" size="3">loops
 iterate through a set of values until the list is exhausted:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/for.sh.txt"><font face="Times New Roman" size=
 "3">for.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">for i in 1 2 3 4 5</font>
 </pre>
 <pre>
 <font size="2">do</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "Looping ... number $i"</font>
 </pre>
 <pre>
 <font size="2">done</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Try this code and see what it does. Note that the values can be
 anything at all:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/for2.sh.txt"><font face="Times New Roman" size=
 "3">for2.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">for i in hello 1 * 2 goodbye </font>
 </pre>
 <pre>
 <font size="2">do</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "Looping ... i is set to $i"</font>
 </pre>
 <pre>
 <font size="2">done</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">is well worth trying. Make sure that you understand what is happening
 here. Try it without the</font> <code><span style=
 "font-size: 10pt">*</span></code> <font face="Times New Roman" size="3">and
 grasp the idea, then re-read the</font> <a href=
 "http://steve-parker.org/sh/wildcards.shtml"><font face="Times New Roman" size=
 "3">Wildcards</font></a> <font face="Times New Roman" size="3">section and try
 it again with the</font> <code><span style="font-size: 10pt">*</span></code>
 <font face="Times New Roman" size="3">in place. Try it also in different
 directories, and with the</font> <code><span style=
 "font-size: 10pt">*</span></code> <font face="Times New Roman" size=
 "3">surrounded by double quotes, and try it preceded by a backslash
 (</font><code><span style="font-size: 10pt">*</span></code><font face=
 "Times New Roman" size="3">)</font></p>
 <p><font face="Times New Roman" size="3">In case you don't have access to a
 shell at the moment (it is very useful to have a shell to hand whilst reading
 this tutorial), the results of the above two scripts are:</font></p>
 <pre>
 <font size="2">Looping .... number 1</font>
 </pre>
 <pre>
 <font size="2">Looping .... number 2</font>
 </pre>
 <pre>
 <font size="2">Looping .... number 3</font>
 </pre>
 <pre>
 <font size="2">Looping .... number 4</font>
 </pre>
 <pre>
 <font size="2">Looping .... number 5</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">and, for the second example:</font></p>
 <pre>
 <font size="2">Looping ... i is set to hello</font>
 </pre>
 <pre>
 <font size="2">Looping ... i is set to 1</font>
 </pre>
 <pre>
 <font size=
 "2">Looping ... i is set to (name of first file in current directory)</font>
 </pre>
 <pre>
 <font size="2"><span style="mso-spacerun: yes">   </span>... etc ...</font>
 </pre>
 <pre>
 <font size=
 "2">Looping ... i is set to (name of last file in current directory)</font>
 </pre>
 <pre>
 <font size="2">Looping ... i is set to 2</font>
 </pre>
 <pre>
 <font size="2">Looping ... i is set to goodbye</font>
 </pre>
 <p><font face="Times New Roman" size="3">So, as you can see,</font>
 <code><span style="font-size: 10pt">for</span></code> <font face=
 "Times New Roman" size="3">simply loops through whatever input it is given,
 until it runs out of input.</font> <a name="while"></a></p>
 <h2 style="margin: 12pt 0in 3pt"><span style="mso-bookmark: while"><em>While
 Loops</em></span></h2>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><span style=
 "mso-bookmark: while"><code><span style="font-size: 10pt">while</span></code>
 <font face="Times New Roman" size="3">loops can be much more fun! (depending on
 your idea of fun, and how often you get out of the house... )</font></span></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/while.sh.txt"><font face="Times New Roman" size=
 "3">while.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">INPUT_STRING=hello</font>
 </pre>
 <pre>
 <font size="2">while [ "$INPUT_STRING" != "bye" ]</font>
 </pre>
 <pre>
 <font size="2">do</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "Please type something in (bye to quit)"</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>read INPUT_STRING</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "You typed: $INPUT_STRING"</font>
 </pre>
 <pre>
 <font size="2">done</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">What happens here, is that the echo and read statements will run
 indefinitely until you type "bye" when prompted.<br>
 Review</font> <a href="http://steve-parker.org/sh/variables1.shtml"><font face=
 "Times New Roman" size="3">Variables - Part I</font></a> <font face=
 "Times New Roman" size="3">to see why we set</font> <code><span style=
 "font-size: 10pt">INPUT_STRING=hello</span></code> <font face="Times New Roman"
 size="3">before testing it. This makes it a repeat loop, not a traditional
 while loop.</font></p>
 <p><font face="Times New Roman" size="3">The colon (</font><code><span style=
 "font-size: 10pt">:</span></code><font face="Times New Roman" size="3">) always
 evaluates to true; whilst using this can be necessary sometimes, it is often
 preferrable to use a real exit condition. Compare quitting the above loop with
 the one below; see which is the more elegant. Also think of some situations in
 which each one would be more useful than the other:</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/while2.sh.txt"><font face="Times New Roman"
 size="3">while2.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">while :</font>
 </pre>
 <pre>
 <font size="2">do</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "Please type something in (^C to quit)"</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>read INPUT_STRING</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "You typed: $INPUT_STRING"</font>
 </pre>
 <pre>
 <font size="2">done</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Another useful trick is the</font> <code><span style=
 "font-size: 10pt">while read f</span></code> <font face="Times New Roman" size=
 "3">loop. This example uses the</font> <a href=
 "http://steve-parker.org/sh/case.shtml"><font face="Times New Roman" size=
 "3">case</font></a> <font face="Times New Roman" size="3">statement, which
 we'll cover later. It reads from the file</font> <code><span style=
 "font-size: 10pt">myfile</span></code><font face="Times New Roman" size="3">,
 and for each line, tells you what language it thinks is being used. Each line
 must end with a LF (newline) - if</font> <code><span style=
 "font-size: 10pt">cat myfile</span></code> <font face="Times New Roman" size=
 "3">doesn't end with a blank line, that final line will not be
 processed.</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/while3a.sh.txt"><font face="Times New Roman"
 size="3">while3a.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">while read f</font>
 </pre>
 <pre>
 <font size="2">do</font>
 </pre>
 <pre>
 <font size="2"><span style="mso-spacerun: yes">  </span>case $f in</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-tab-count: 1">     </span>hello)<span style=
 "mso-tab-count: 2">     </span>echo English<span style=
 "mso-tab-count: 1">  </span>;;</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-tab-count: 1">     </span>howdy)<span style=
 "mso-tab-count: 2">     </span>echo American<span style=
 "mso-tab-count: 1">  </span>;;</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-tab-count: 1">     </span>gday)<span style=
 "mso-tab-count: 2">      </span>echo Australian<span style=
 "mso-tab-count: 1"> </span>;;</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-tab-count: 1">     </span>bonjour)<span style=
 "mso-tab-count: 1">    </span>echo French<span style=
 "mso-tab-count: 1">   </span>;;</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-tab-count: 1">     </span>"guten tag")<span style=
 "mso-tab-count: 1">  </span>echo German<span style=
 "mso-tab-count: 1">   </span>;;</font>
 </pre>
 <pre>
 <font size="2"><span style="mso-tab-count: 1">     </span>*)<span style=
 "mso-tab-count: 2">       </span>echo Unknown Language: $f</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-tab-count: 2">        </span>;;</font>
 </pre>
 <pre>
 <font size="2"><span style="mso-spacerun: yes">  </span>esac</font>
 </pre>
 <pre>
 <font size="2">done &lt; myfile</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">On many Unix systems, this can be also be done as</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/while3b.sh.txt"><font face="Times New Roman"
 size="3">while3b.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">while f=`line`</font>
 </pre>
 <pre>
 <font size="2">do</font>
 </pre>
 <pre>
 <font size="2"><span style="mso-spacerun: yes">  </span>.. process f ..</font>
 </pre>
 <pre>
 <font size="2">done &lt; myfile</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">But since the</font> <code><span style="font-size: 10pt">while read
 f</span></code> <font face="Times New Roman" size="3">works with any *nix, and
 doesn't depend on the external program</font> <code><span style=
 "font-size: 10pt">line</span></code><font face="Times New Roman" size="3">, the
 former is preferable. See</font> <a href=
 "http://steve-parker.org/sh/external.shtml"><font face="Times New Roman" size=
 "3">External Programs</font></a> <font face="Times New Roman" size="3">to see
 why this method uses the backtick (`).<br>
 Had I referred to</font> <code><span style="font-size: 10pt">$i</span></code>
 <font face="Times New Roman" size="3">(not</font> <code><span style=
 "font-size: 10pt">$f</span></code><font face="Times New Roman" size="3">) in
 the default ("Unknown Language") case above - you will get no warnings or
 errors in this case, even though</font> <code><span style=
 "font-size: 10pt">$i</span></code> <font face="Times New Roman" size="3">has
 not been declared or defined. For example:</font></p>
 <pre>
 <font size="2">$ i=THIS_IS_A_BUG</font>
 </pre>
 <pre>
 <font size="2">$ export i</font>
 </pre>
 <pre>
 <font size="2">$ ./while3.sh something</font>
 </pre>
 <pre>
 <font size="2">Unknown Language: THIS_IS_A_BUG</font>
 </pre>
 <pre>
 <font size="2">$</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">So make sure that you avoid typos. This is also another good reason
 for using</font> <code><span style="font-size: 10pt">${x}</span></code>
 <font face="Times New Roman" size="3">and not just</font> <code><span style=
 "font-size: 10pt">$x</span></code> <font face="Times New Roman" size="3">-
 if</font> <code><span style="font-size: 10pt">x="A"</span></code> <font face=
 "Times New Roman" size="3">and you want to say "A1", you need</font>
 <code><span style="font-size: 10pt">echo ${x}1</span></code><font face=
 "Times New Roman" size="3">, as</font> <code><span style="font-size: 10pt">echo
 $x1</span></code> <font face="Times New Roman" size="3">will try to use the
 variable</font> <code><span style="font-size: 10pt">x1</span></code><font face=
 "Times New Roman" size="3">, which may not exist, or may be set to</font>
 <code><span style="font-size: 10pt">B2</span></code><font face=
 "Times New Roman" size="3">.</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">I recently found an old thread on Usenet which I had been involved in,
 where I actually learned more ...</font> <a href=
 "http://groups.google.com/groups?hl=en&amp;safe=off&amp;selm=D9I1pp.JM%40info.bris.ac.uk">
 <font face="Times New Roman" size="3">Google has it here.</font></a><font face=
 "Times New Roman" size="3">.</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">A handy Bash (but not Bourne Shell) tip I learned recently from
 the</font> <a href="http://www.linuxfromscratch.org/"><font face=
 "Times New Roman" size="3">Linux From Scratch</font></a> <font face=
 "Times New Roman" size="3">project is:</font></p>
 <pre>
 <font size="2">mkdir rc{0,1,2,3,4,5,6,S}.d</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">instead of the more cumbersome:</font></p>
 <pre>
 <font size="2">for runlevel in 0 1 2 3 4 5 6 S</font>
 </pre>
 <pre>
 <font size="2">do</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>mkdir rc${runlevel}.d</font>
 </pre>
 <pre>
 <font size="2">done</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">And this can be done recursively, too:</font></p>
 <pre>
 <font size="2">$ cd /</font>
 </pre>
 <pre>
 <font size="2">$ ls -ld {,usr,usr/local}/{bin,sbin,lib}</font>
 </pre>
 <pre>
 <font size="2">drwxr-xr-x<span style=
 "mso-spacerun: yes">   </span>2 root<span style=
 "mso-spacerun: yes">   </span>root<span style=
 "mso-spacerun: yes">     </span>4096 Oct 26 01:00 /bin</font>
 </pre>
 <pre>
 <font size="2">drwxr-xr-x<span style=
 "mso-spacerun: yes">   </span>6 root<span style=
 "mso-spacerun: yes">   </span>root<span style=
 "mso-spacerun: yes">     </span>4096 Jan 16 17:09 /lib</font>
 </pre>
 <pre>
 <font size="2">drwxr-xr-x<span style=
 "mso-spacerun: yes">   </span>2 root<span style=
 "mso-spacerun: yes">   </span>root<span style=
 "mso-spacerun: yes">     </span>4096 Oct 27 00:02 /sbin</font>
 </pre>
 <pre>
 <font size="2">drwxr-xr-x<span style=
 "mso-spacerun: yes">   </span>2 root<span style=
 "mso-spacerun: yes">   </span>root<span style=
 "mso-spacerun: yes">     </span>40960 Jan 16 19:35 usr/bin</font>
 </pre>
 <pre>
 <font size="2">drwxr-xr-x<span style=
 "mso-spacerun: yes">  </span>83 root<span style=
 "mso-spacerun: yes">   </span>root<span style=
 "mso-spacerun: yes">     </span>49152 Jan 16 17:23 usr/lib</font>
 </pre>
 <pre>
 <font size="2">drwxr-xr-x<span style=
 "mso-spacerun: yes">   </span>2 root<span style=
 "mso-spacerun: yes">   </span>root<span style=
 "mso-spacerun: yes">     </span>4096 Jan 16 22:22 usr/local/bin</font>
 </pre>
 <pre>
 <font size="2">drwxr-xr-x<span style=
 "mso-spacerun: yes">   </span>3 root<span style=
 "mso-spacerun: yes">   </span>root<span style=
 "mso-spacerun: yes">     </span>4096 Jan 16 19:17 usr/local/lib</font>
 </pre>
 <pre>
 <font size="2">drwxr-xr-x<span style=
 "mso-spacerun: yes">   </span>2 root<span style=
 "mso-spacerun: yes">   </span>root<span style=
 "mso-spacerun: yes">     </span><span style=
 "mso-spacerun: yes"> </span>4096 Dec 28 00:44 usr/local/sbin</font>
 </pre>
 <pre>
 <font size="2">drwxr-xr-x<span style=
 "mso-spacerun: yes">   </span>2 root<span style=
 "mso-spacerun: yes">   </span>root<span style=
 "mso-spacerun: yes">     </span>8192 Dec 27 02:10 usr/sbin</font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <h1 style="margin: 12pt 0in 3pt"><font size="5">We will use while loops further
 in the</font> <a href="http://steve-parker.org/sh/test.shtml"><font size=
 "5">Test</font></a> <font size="5">and</font> <a href=
 "http://steve-parker.org/sh/case.shtml"><font size="5">Case</font></a>
 <font size="5">sections. Test</font></h1>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Test is used by virtually every shell script written. It may not seem
 that way, because</font> <code><span style="font-size: 10pt">test</span></code>
 <font face="Times New Roman" size="3">is not often called directly.</font>
 <code><span style="font-size: 10pt">test</span></code> <font face=
 "Times New Roman" size="3">is more frequently called as</font>
 <code><span style="font-size: 10pt">[</span></code><font face="Times New Roman"
 size="3">.</font> <code><span style="font-size: 10pt">[</span></code>
 <font face="Times New Roman" size="3">is a symbolic link to test, just to make
 shell programs more readable. If is also normally a shell builtin (which means
 that the shell itself will interpret [ as meaning test, even if your Unix
 environment is set up differently):</font></p>
 <pre>
 <font size="2">$ type [</font>
 </pre>
 <pre>
 <font size="2">[ is a shell builtin</font>
 </pre>
 <pre>
 <font size="2">$ which [</font>
 </pre>
 <pre>
 <font size="2">/usr/bin/[</font>
 </pre>
 <pre>
 <font size="2">$ ls -l /usr/bin/[</font>
 </pre>
 <pre>
 <font size=
 "2">lrwxrwxrwx 1 root root 4 Mar 27 2000 /usr/bin/[ -&gt; test</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">This means that '[' is actually a program, just like</font>
 <code><span style="font-size: 10pt">ls</span></code> <font face=
 "Times New Roman" size="3">and other programs, so it must be surrounded by
 spaces:</font></p>
 <pre>
 <font size="2">if [$foo == "bar" ]</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">will not work; it is interpreted as</font> <code><span style=
 "font-size: 10pt">if test$foo == "bar" ]</span></code><font face=
 "Times New Roman" size="3">, which is a ']' without a beginning '['. Put spaces
 around all your operators I've highlighted the mandatory spaces with the word
 'SPACE' - replace 'SPACE' with an actual space; if there isn't a space there,
 it won't work:</font></p>
 <pre>
 <font size="2">if SPACE [ SPACE "$foo" SPACE == SPACE "bar" SPACE ]</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><br>
 <font face="Times New Roman" size="3">Test is a simple but powerful comparison
 utility. For full details, run</font> <code><span style="font-size: 10pt">man
 test</span></code> <font face="Times New Roman" size="3">on your system, but
 here are some usages and typical examples.</font></p>
 <p><font face="Times New Roman" size="3">Test is most often invoked indirectly
 via the</font> <code><span style="font-size: 10pt">if</span></code> <font face=
 "Times New Roman" size="3">and</font> <code><span style=
 "font-size: 10pt">while</span></code> <font face="Times New Roman" size=
 "3">statements. It is also the reason you will come into difficulties if you
 create a program called</font> <code><span style=
 "font-size: 10pt">test</span></code> <font face="Times New Roman" size="3">and
 try to run it, as this shell builtin will be called instead of your
 program!<br>
 The syntax for</font> <code><span style=
 "font-size: 10pt">if...then...else...</span></code> <font face=
 "Times New Roman" size="3">is:</font></p>
 <pre>
 <font size="2">if [ ... ]</font>
 </pre>
 <pre>
 <font size="2">then</font>
 </pre>
 <pre>
 <font size="2"><span style="mso-spacerun: yes">  </span># if-code</font>
 </pre>
 <pre>
 <font size="2">else</font>
 </pre>
 <pre>
 <font size="2"><span style="mso-spacerun: yes">  </span># else-code</font>
 </pre>
 <pre>
 <font size="2">fi</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Note that</font> <code><span style="font-size: 10pt">fi</span></code>
 <font face="Times New Roman" size="3">is</font> <code><span style=
 "font-size: 10pt">if</span></code> <font face="Times New Roman" size=
 "3">backwards! This is used again later with</font> <a href=
 "http://steve-parker.org/sh/case.shtml"><font face="Times New Roman" size=
 "3">case</font></a> <font face="Times New Roman" size="3">and</font>
 <code><span style="font-size: 10pt">esac</span></code><font face=
 "Times New Roman" size="3">.<br>
 Also, be aware of the syntax - the "if [ ... ]" and the "then" commands must be
 on different lines. Alternatively, the semicolon ";" can seperate
 them:</font></p>
 <pre>
 <font size="2">if [ ... ]; then</font>
 </pre>
 <pre>
 <font size="2"><span style="mso-spacerun: yes">  </span># do something</font>
 </pre>
 <pre>
 <font size="2">fi</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">You can also use the</font> <code><span style=
 "font-size: 10pt">elif</span></code><font face="Times New Roman" size="3">,
 like this:</font></p>
 <pre>
 <font size="2">if<span style=
 "mso-spacerun: yes">  </span>[ something ]; then</font>
 </pre>
 <pre>
 <font size="2"> echo "Something"</font>
 </pre>
 <pre>
 <font size="2"> elif [ something_else ]; then</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "Something else"</font>
 </pre>
 <pre>
 <font size="2"> else</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "None of the above"</font>
 </pre>
 <pre>
 <font size="2">fi</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">This will echo "Something" if the</font> <code><span style=
 "font-size: 10pt">[ something ]</span></code> <font face="Times New Roman"
 size="3">test succeeds, otherwise it will test</font> <code><span style=
 "font-size: 10pt">[ something_else ]</span></code><font face="Times New Roman"
 size="3">, and echo "Something else" if that succeeds. If all else fails, it
 will echo "None of the above".</font></p>
 <p><font face="Times New Roman" size="3">Try the following code snippet, before
 running it set the variable X to various values (try -1, 0, 1, hello, bye,
 etc). You can do this as follows (thanks to Dave for pointing out the need to
 export the variable, as noted in</font> <a href=
 "http://steve-parker.org/sh/variables1.shtml"><font face="Times New Roman"
 size="3">Variables - Part I</font></a><font face="Times New Roman" size=
 "3">.):</font></p>
 <pre>
 <font size="2">$ X=5</font>
 </pre>
 <pre>
 <font size="2">$ export X</font>
 </pre>
 <pre>
 <font size="2">$ ./test.sh</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>... output of test.sh ...</font>
 </pre>
 <pre>
 <font size="2">$ X=hello</font>
 </pre>
 <pre>
 <font size="2">$ ./test.sh</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>... output of test.sh ...</font>
 </pre>
 <pre>
 <font size="2">$ X=test.sh</font>
 </pre>
 <pre>
 <font size="2">$ ./test.sh</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>... output of test.sh ...</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Then try it again, with</font> <code><span style=
 "font-size: 10pt">$X</span></code> <font face="Times New Roman" size="3">as the
 name of an existing file, such as</font> <code><span style=
 "font-size: 10pt">/etc/hosts</span></code><font face="Times New Roman" size=
 "3">.</font></p>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "http://steve-parker.org/sh/eg/test.sh.txt"><font face="Times New Roman" size=
 "3">test.sh</font></a></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size="2">if [ "$X" -lt "0" ]</font>
 </pre>
 <pre>
 <font size="2">then</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "X is less than zero"</font>
 </pre>
 <pre>
 <font size="2">fi</font>
 </pre>
 <pre>
 <font size="2">if [ "$X" -gt "0" ]; then</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "X is more than zero"</font>
 </pre>
 <pre>
 <font size="2">fi</font>
 </pre>
 <pre>
 <font size="2">[ "$X" -le "0" ] &amp;&amp; </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "X is less than or equal to<span style=
 "mso-spacerun: yes">  </span>zero"</font>
 </pre>
 <pre>
 <font size="2">[ "$X" -ge "0" ] &amp;&amp; </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "X is more than or equal to zero"</font>
 </pre>
 <pre>
 <font size="2">[ "$X" = "0" ] &amp;&amp; </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "X is the string or number "0""</font>
 </pre>
 <pre>
 <font size="2">[ "$X" = "hello" ] &amp;&amp; </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "X matches the string "hello""</font>
 </pre>
 <pre>
 <font size="2">[ "$X" != "hello" ] &amp;&amp; </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "X is not the string "hello""</font>
 </pre>
 <pre>
 <font size="2">[ -n "$X" ] &amp;&amp; </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "X is of nonzero length"</font>
 </pre>
 <pre>
 <font size="2">[ -f "$X" ] &amp;&amp; </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "X is the path of a real file" || </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "No such file: $X"</font>
 </pre>
 <pre>
 <font size="2">[ -x "$X" ] &amp;&amp; </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "X is the path of an executable file"</font>
 </pre>
 <pre>
 <font size="2">[ "$X" -nt "/etc/passwd" ] &amp;&amp; </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">    </span>echo "X is a file which is newer than /etc/passwd" </font>
 </pre>
 <div class="MsoNormal" style="margin: 0in 0in 0pt">
 <hr align="left" width="40%" color="#ACA899" noshade="noshade" size="2"></div>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">Note that we can use the semicolon (;) to join two lines together.
 This is often done to save a bit of space in simple</font> <code><span style=
 "font-size: 10pt">if</span></code> <font face="Times New Roman" size=
 "3">statements. The backslash simply tells the shell that this is not the end
 of the line, but the two (or more) lines should be treated as one. This is
 useful for readability. It is customary to indent the following
 line.</font></p>
 <p><font face="Times New Roman" size="3">As we see from these examples,</font>
 <code><span style="font-size: 10pt">test</span></code> <font face=
 "Times New Roman" size="3">can perform many tests on numbers, strings, and
 filenames.</font></p>
 <p><font face="Times New Roman" size="3">There is a simpler way of
 writing</font> <code><span style="font-size: 10pt">if</span></code> <font face=
 "Times New Roman" size="3">statements: The</font> <code><span style=
 "font-size: 10pt">&amp;&amp;</span></code> <font face="Times New Roman" size=
 "3">and</font> <code><span style="font-size: 10pt">||</span></code> <font face=
 "Times New Roman" size="3">commands give code to run if the result is
 true.</font></p>
 <pre>
 <font size="2">#!/bin/sh</font>
 </pre>
 <pre>
 <font size=
 "2">[ $X -ne 0 ] &amp;&amp; echo "X isn't zero" || echo "X is zero"</font>
 </pre>
 <pre>
 <font size=
 "2">[ -f $X ] &amp;&amp; echo "X is a file" || echo "X is not a file"</font>
 </pre>
 <pre>
 <font size="2">[ -n $X ] &amp;&amp; echo "X is of non-zero length" || </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">   </span>echo "X is of zero length"</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">This syntax is possible because there is a file (or shell-builtin)
 called</font> <code><span style="font-size: 10pt">[</span></code> <font face=
 "Times New Roman" size="3">which is linked to</font> <code><span style=
 "font-size: 10pt">test</span></code><font face="Times New Roman" size="3">. Be
 careful using this construct, though, as overuse can lead to very hard-to-read
 code. The</font> <code><span style=
 "font-size: 10pt">if...then...else...</span></code> <font face=
 "Times New Roman" size="3">structure is much more readable. Use of the</font>
 <code><span style="font-size: 10pt">[...]</span></code> <font face=
 "Times New Roman" size="3">construct is recommended for while loops and trivial
 sanity checks with which you do not want to overly distract the
 reader.</font></p>
 <p><font face="Times New Roman" size="3">Note that when you set X to a
 non-numeric value, the first few comparisons result in the message:</font></p>
 <pre>
 <font size="2">test.sh: [: integer expression expected before -lt</font>
 </pre>
 <pre>
 <font size="2">test.sh: [: integer expression expected before -gt</font>
 </pre>
 <pre>
 <font size="2">test.sh: [: integer expression expected before -le</font>
 </pre>
 <pre>
 <font size="2">test.sh: [: integer expression expected before -ge</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">This is because the -lt, -gt, -le, -ge, comparisons are only designed
 for integers, and do not work on strings. The string comparisons, such
 as</font> <code><span style="font-size: 10pt">!=</span></code> <font face=
 "Times New Roman" size="3">will happily treat "5" as a string, but there is no
 sensible way of treating "Hello" as an integer, so the integer comparisons
 complain.<br>
 If you want your shell script to behave more gracefully, you will have to check
 the contents of the variable before you test it - maybe something like
 this:</font></p>
 <pre>
 <font size="2">echo $X | grep [^0-9] &gt; /dev/null 2&gt;&amp;1</font>
 </pre>
 <pre>
 <font size="2">if [ "$?" -eq "0" ]; then</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span># If the grep found something other than 0-9</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span># then it's not an integer.</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>echo "Sorry, wanted a number"</font>
 </pre>
 <pre>
 <font size="2">else</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span># The grep found only 0-9, so it's an integer. </font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes"> </span># We can safely do a test on it.</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">  </span>if [ "$X" -eq "7" ]; then</font>
 </pre>
 <pre>
 <font size="2"><span style=
 "mso-spacerun: yes">   </span>echo "You entered the magic number!"</font>
 </pre>
 <pre>
 <font size="2"><span style="mso-spacerun: yes">  </span>fi</font>
 </pre>
 <pre>
 <font size="2">fi</font>
 </pre>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">In this way you can</font> <code><span style=
 "font-size: 10pt">echo</span></code> <font face="Times New Roman" size="3">a
 more meaningful message to the user, and exit gracefully. The</font>
 <code><span style="font-size: 10pt">$?</span></code> <font face=
 "Times New Roman" size="3">variable is explained in</font> <a href=
 "http://steve-parker.org/sh/variables2.shtml"><font face="Times New Roman"
 size="3">Variables - Part II</font></a><font face="Times New Roman" size="3">,
 and</font> <code><span style="font-size: 10pt">grep</span></code> <font face=
 "Times New Roman" size="3">is a complicated beast, so here goes:</font>
 <code><span style="font-size: 10pt">grep [0-9]</span></code> <font face=
 "Times New Roman" size="3">finds lines of text which contain digits (0-9) and
 possibly other characters, so the carat (</font><code><span style=
 "font-size: 10pt">^</span></code><font face="Times New Roman" size="3">)
 in</font> <code><span style="font-size: 10pt">grep [^0-9]</span></code>
 <font face="Times New Roman" size="3">finds only those lines which don't
 consist only of numbers. We can then take the opposite (by acting on failure,
 not success). Okay? The</font> <code><span style=
 "font-size: 10pt">&gt;/dev/null 2&gt;&amp;1</span></code> <font face=
 "Times New Roman" size="3">directs any output or errors to the special "null"
 device, instead of going to the user's screen.<br>
 Many thanks to Paul Schermerhorn for correcting me - this page used to claim
 that</font> <code><span style="font-size: 10pt">grep -v [0-9]</span></code></p>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><font face="Times New Roman"
 size="3">would work, but this is clearly far too simplistic.</font></p>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"></p>
 <p class="MsoNormal" style="margin: 0in 0in 0pt"><a href=
 "/page/BOURNE%20SHELL%20CONTINUE...%20">next&gt;&gt;</a></p>