Added section on comments. Started section on quotes. Still not ready to be

published.
This commit is contained in:
franl 2002-11-01 22:01:22 +00:00
parent 07c456a5bf
commit 7b3c4ef3d4
1 changed files with 210 additions and 71 deletions

View File

@ -1,5 +1,12 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Author's note to self: switch to this DTD before committing this file
into CVS:
http://docbook.org/xml/4.1.2/docbookx.dtd
-->
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://docbook.org/xml/4.1.2/docbookx.dtd" [
<!ENTITY ldp "Linux Documentation Project">
@ -228,16 +235,16 @@
<title>What and Where is Bash?</title>
<para>
Bash is a <emphasis>shell</emphasis>, which is a program that reads
Bash is a <firstterm>shell</firstterm>, which is a program that reads
commands and executes them. Sometimes, the commands that Bash reads come
directly from the keyboard as you type them. When this happens, we say
that Bash is an <emphasis>interactive</emphasis> shell. If you've ever
that Bash is an <firstterm>interactive</firstterm> shell. If you've ever
logged into a UNIX system, then you've probably used an interactive shell.
Bash is the default interactive shell of the GNU/Linux system (and you
might also find it installed on commercial UNIX systems). Sometimes, the
commands that Bash reads come from a file called a <emphasis>shell
script</emphasis>. When this happens, we say that Bash is a
<emphasis>non-interactive</emphasis> shell. In this case, Bash reads each
commands that Bash reads come from a file called a <firstterm>shell
script</firstterm>. When this happens, we say that Bash is a
<firstterm>non-interactive</firstterm> shell. In this case, Bash reads each
line of the script file from top to bottom, executing each command as if
it had been typed on the keyboard.
</para>
@ -247,7 +254,7 @@
Bash in <filename>/bin/bash</filename>. On commerical UNIX systems, such
as Solaris or HP-UX, you might find it in the same place, or it might be
in <filename>/usr/local/bin/bash</filename>. You rarely need to run Bash
directly, but you need to know where Bash is located on your system, so
directly, but you need to know where Bash is located on your system so
that you can write the very first line of your Bash scripts correctly.
</para>
@ -282,7 +289,7 @@
<para>
Let's start with a simple Bash script and work up to more complex ones
later. Just about the simplest program you can write in any programming
language is a <emphasis>Hello world</emphasis> program, which is a program
language is a <emphasis>Hello World</emphasis> program, which is a program
that simply outputs the text "Hello world". <xref
linkend="ex-hello-script"/> shows a Bash script to do that.
</para>
@ -290,7 +297,7 @@
<para>
<blockquote>
<example id="ex-hello-script">
<title>A Simple <emphasis>Hello world</emphasis> Script</title>
<title>A Simple <emphasis>Hello World</emphasis> Script</title>
<programlisting>
#!/bin/bash
echo Hello world</programlisting>
@ -300,7 +307,7 @@ echo Hello world</programlisting>
<para>
<xref linkend="ex-hello-script"/> shows a very simple two-line Bash script.
Create this script by simply typing those two lines into a file using your
Create this script by typing those two lines into a file using your
favorite text editor. The name of the file can be anything you choose,
but you should <emphasis>not</emphasis> name the file
"<filename>test</filename>", because there is a built-in
@ -327,7 +334,7 @@ echo Hello world</programlisting>
<title>Running the <emphasis>Hello World</emphasis> Script</title>
<para>
Once you've created your <emphasis>Hello world</emphasis> script, you can
Once you've created your <emphasis>Hello World</emphasis> script, you can
execute it in a variety of ways. Let's assume that you named the script
<filename>hello</filename> and it exists in your current working
directory. <xref linkend="ex-running-hello"/> shows how to execute the
@ -360,13 +367,13 @@ Hello world</programlisting>
The command "<computeroutput><command>bash
hello</command></computeroutput>" starts a non-interactive Bash shell and
passes it the name of the file containing the script to execute. While
the script is running, there are actually <emphasis>two</emphasis> Bash
the script is running, there are actually <emphasis>two</emphasis>
shells running! One is the interactive Bash shell which displays the
"<computeroutput>bash$</computeroutput>" prompt and executes the command
"<computeroutput><command>bash hello</command></computeroutput>". The
other is the non-interactive Bash shell that you manually started to
execute the script. In <xref linkend="ex-running-hello"/>, the
interactive shell is Bash, but you don't have to be using Bash as your
interactive shell is Bash, but you don't have to use Bash as your
interactive shell to run a Bash script. The command shown in <xref
linkend="ex-running-hello"/> will work no matter which interactive shell
you use.
@ -387,12 +394,12 @@ Hello world</programlisting>
<listitem>
<para>
Change the permissions on the script to allow you to execute it. This
can be done with the command "<computeroutput><command>chmod u+x
hello</command></computeroutput>". You don't have to grant execute
permission just to yourself. The command
"<computeroutput><command>chmod ugo+x
hello</command></computeroutput>" allows everyone to execute your
script.
can be done with the command
"<computeroutput><command>chmod&nbsp;u+x&nbsp;hello</command></computeroutput>".
You don't have to grant execute permission just to yourself. The
command
"<computeroutput><command>chmod&nbsp;ugo+x&nbsp;hello</command></computeroutput>"
allows everyone to execute your script.
</para>
</listitem>
@ -413,18 +420,19 @@ Hello world</programlisting>
<orderedlist>
<listitem>
<para>
Create a directory named "<filename>bin</filename>"
under your home directory. You can do that with the command
"<computeroutput><command>mkdir $HOME/bin</command></computeroutput>"
or "<computeroutput><command>cd; mkdir bin</command></computeroutput>".
Create a directory named "<filename>bin</filename>" under your home
directory. You can do that with the command
"<computeroutput><command>mkdir&nbsp;$HOME/bin</command></computeroutput>"
or
"<computeroutput><command>cd;&nbsp;mkdir&nbsp;bin</command></computeroutput>".
</para>
</listitem>
<listitem>
<para>
Put the script in that directory. You can do that with the command
"<computeroutput><command>mv hello $HOME/bin</command></computeroutput>"
or "<computeroutput><command>mv hello ~/bin</command></computeroutput>".
"<computeroutput><command>mv&nbsp;hello&nbsp;$HOME/bin</command></computeroutput>"
or "<computeroutput><command>mv hello&nbsp;~/bin</command></computeroutput>".
</para>
</listitem>
@ -439,6 +447,8 @@ Hello world</programlisting>
<blockquote>
<computeroutput>PATH="$HOME/bin:$PATH"</computeroutput>
</blockquote>
We cover variables in more detail in <xref linkend="sect-variables"/>.
</para>
</listitem>
@ -504,8 +514,8 @@ Hello world</programlisting>
("<computeroutput>#!/bin/bash</computeroutput>") tells the operating
system which shell to spawn to execute this script. Unlike programs
written in compiled languages, such as C, Pascal, or C++, a Bash script is
<emphasis>interpreted</emphasis>, which means that some other program (the
<emphasis>interpreter</emphasis>) must read the script and execute the
<firstterm>interpreted</firstterm>, which means that some other program (the
<firstterm>interpreter</firstterm>) must read the script and execute the
commands in the script. Bash is the interpreter for a Bash script. A
good analogy is to think of a chef cooking a meal by reading a recipe. In
this case, your script is the recipe, and Bash is the chef.
@ -519,10 +529,9 @@ Hello world</programlisting>
where it is installed and write the first line of your script accordingly.
If you are using Linux, then Bash is always installed in
<filename>/bin/bash</filename>. The first line in a shell script is
sometimes called the <emphasis>shebang</emphasis> line. This term is
sometimes called the <firstterm>shebang</firstterm> line. This term is
derived from the use of the word "bang" to refer to an exclaimation mark
and the fact that the first line of a shell script names a shell. It is
also called the <emphasis>pound-bang</emphasis> line.
and the fact that the first line of a shell script names a shell.
</para>
<para>
@ -552,9 +561,10 @@ Hello world</programlisting>
<para>
The answer is: nothing. The text between a
"<computeroutput>#</computeroutput>" character and the end of the same
line is a <emphasis>comment</emphasis>. A comment is completely ignored
line is a <firstterm>comment</firstterm>. A comment is completely ignored
by Bash. You should use comments to make your script readable by others
by including information that helps the reader understand your script.
We cover comments in more detail in <xref linkend="sect-comments"/>.
Since the "<computeroutput>#!/bin/bash</computeroutput>" line is ignored
by Bash, why can't you leave it out? Although it is ignored by Bash, it
is not ignored by the operating system, which uses the first line of the
@ -641,17 +651,141 @@ Hello world</programlisting>
<sect2 id="sect-comments">
<title>Comments</title>
<para>*** UNDER CONSTRUCTION ***</para>
<!--
*************************************************************
* UNDER CONSTRUCTION *
*************************************************************
-->
A Bash script should contain comments. Comments are ignored by Bash, but
they help the person who reads the script to understand it. A comment is any
text following a "<computeroutput>#</computeroutput>" character on the
same line. The "<computeroutput>#</computeroutput>" character must be the
first character in a word. <xref linkend="ex-comments"/> shows a script
containing some comments. This is also the first script we've seen that
contains blank lines. Bash ignores blank lines, so you can use them to
make your script more readable.
<para>
<blockquote>
<example id="ex-comments">
<title>Using Comments</title>
<programlisting>
#!/bin/bash
# This script is an example of using comments.
echo Hello world # This comment shares a line with a command!
# The next line does _not_ contain a comment! Do you see why?
echo Hello#world
# This is also a comment. The "#" doesn't have to be in the leftmost
# column. Compare the next echo command with # the previous echo
# command. One little space can make a big difference!
echo Hello #world</programlisting>
</example>
</blockquote>
</para>
<para>
The first line in the script shown in <xref linkend="ex-comments"/> is the
classic shebang line, described earlier. The comments should be fairly
easy to see. The line that reads
"<computeroutput>echo&nbsp;Hello#world</computeroutput>" also contains a
"<computeroutput>#</computeroutput>" character, but there is
<emphasis>no</emphasis> comment on that line, because the
"<computeroutput>#</computeroutput>" does not occur at the beginning of a
word. <xref linkend="ex-comments2"/> shows the output produced when this
script is executes (assuming it is in a file named
<filename>comments</filename>).
</para>
<para>
<blockquote>
<example id="ex-comments2">
<title>Using Comments</title>
<programlisting>
bash$ <command>bash comments</command>
Hello world
Hello#world
Hello</programlisting>
</example>
</blockquote>
</para>
<para>
Some people think that writing comments in a script or other kind of
program is a waste of time. Professional software engineers know that is
not true. Software -- and Bash scripts are definitely software -- is hard
to understand if you didn't write it. Even if you wrote it, it can be
hard to understand long afterwards, when it isn't fresh in your mind. You
should aim to have between 20% and 50% of the content of your scripts be
comments.
</para>
</sect2>
<sect2 id="sect-quotes">
<title>Using Quotes</title>
<para>
It is virtually impossible to write a Bash script without using quotes of
one form or another. In a Bash script, the quote characters are:
</para>
<itemizedlist>
<listitem>
<computeroutput>"</computeroutput> &nbsp;&nbsp;&nbsp;(double quote)
</listitem>
<listitem>
<computeroutput>'</computeroutput> &nbsp;&nbsp;&nbsp;(single quote)
</listitem>
<listitem>
<computeroutput>`</computeroutput> &nbsp;&nbsp;&nbsp;(backquote)
</listitem>
<listitem>
<computeroutput>\</computeroutput> &nbsp;&nbsp;&nbsp;(backslash)
</listitem>
</itemizedlist>
<para>
Let's look at each one in turn. The double quote
(<computeroutput>"</computeroutput>) character is the simplest of the
quoting characters. It is used to group multiple space-separated words
together so that Bash treats them as if they were one word. For instance,
if you need to refer to a file that has spaces in its name, you can use
double quotes, as follows:
</para>
<blockquote>
<para>
<computeroutput>cat "meeting agenda.txt"</computeroutput>
</para>
</blockquote>
<para>
In the above command, the
<computeroutput><command>cat</command></computeroutput> command will be
passed a single filename. Had the double quotes been ommitted, the
<computeroutput><command>cat</command></computeroutput> command would have
been passed two filenames, <filename>meeting</filename> and
<filename>agenda.txt</filename>, neither of which exist. It's important
to understand just what the
<computeroutput><command>cat</command></computeroutput> program sees as
its first argument when the above command executes. The
<computeroutput><command>cat</command></computeroutput> program sees
precisely this text as a single command-line argument:
</para>
<blockquote>
<para>
<computeroutput>meeting agenda.txt</computeroutput>
</para>
</blockquote>
<para>
Notice that there are no double quotes in the argument that
<computeroutput><command>cat</command></computeroutput> receives. Quote
characters are shell metacharacters, which means they are removed by Bash
before the command is executed. Even though metacharacters are removed,
they are definitely not ignored by Bash. In the above
<computeroutput><command>cat</command></computeroutput> command, the
double quotes changed how Bash passed the arguments to the program, even
though the program never saw the double quotes!
</para>
<para>*** UNDER CONSTRUCTION ***</para>
<!--
*************************************************************
@ -677,7 +811,7 @@ Hello world</programlisting>
<para>
It's almost impossible to write a non-trivial Bash script without using
<emphasis>I/O redirection</emphasis>. Every UNIX shell, Bash included,
<firstterm>I/O redirection</firstterm>. Every UNIX shell, Bash included,
provides I/O redirection, but the syntax differs between various shells.
Naturally, we'll cover the Bash syntax.
</para>
@ -686,15 +820,15 @@ Hello world</programlisting>
<title>The Standard I/O Streams</title>
<para>
A running program is called a <emphasis>process</emphasis>. When you type a
A running program is called a <firstterm>process</firstterm>. When you type a
command, such as "<computeroutput><command>ls</command></computeroutput>",
Bash spawns a new process to execute the
<computeroutput><command>ls</command></computeroutput> program. The new
process exists only for the time it takes the
"<computeroutput><command>ls</command></computeroutput>" command to execute,
"<computeroutput><command>ls</command></computeroutput>" program to execute,
and then the process terminates. When Bash starts a process to execute a
command, the process is connected to several <emphasis>I/O
streams</emphasis>. An I/O stream is like a hose that has one end
command, the process is connected to several <firstterm>I/O
streams</firstterm>. An I/O stream is like a hose that has one end
connected to the process and the other end connected to a terminal. Data
flows through an I/O stream like water flows through a hose. The data flows
either from the process to the terminal (this is how the process produces
@ -703,8 +837,8 @@ Hello world</programlisting>
</para>
<para>
When a process first starts, there are always three <emphasis>standard I/O
streams</emphasis> connected to the process:
When a process first starts, there are always three <firstterm>standard I/O
streams</firstterm> connected to the process:
</para>
<itemizedlist>
@ -714,10 +848,10 @@ Hello world</programlisting>
</itemizedlist>
<para>
<emphasis>Standard input</emphasis> is the name of the I/O stream through
which a process reads input from its terminal. <emphasis>Standard
output</emphasis> is the name of the I/O stream through which a process
writes output to its terminal. <emphasis>Standard error</emphasis> is the
<firstterm>Standard input</firstterm> is the name of the I/O stream through
which a process reads input from its terminal. <firstterm>Standard
output</firstterm> is the name of the I/O stream through which a process
writes output to its terminal. <firstterm>Standard error</firstterm> is the
name of the I/O stream through which a process writes error messages to
its terminal. These standard I/O streams are sometimes referred to using
their shorthand names: <firstterm>stdin</firstterm>,
@ -725,17 +859,18 @@ Hello world</programlisting>
</para>
<para>
When your Bash script is running, it is a process just like any other, so it
also has these three standard I/O streams. The
<computeroutput><command>echo</command></computeroutput> command writes its
output to standard output. Since standard output is connected by default to
the terminal on which the script is running, the output of the
<computeroutput><command>echo</command></computeroutput> typically appears
on that terminal. But it is possible to <emphasis>redirect</emphasis> an
I/O stream so that it is not connected to the terminal but to a file on
disk. <xref linkend="ex-redirect-stdout"/> shows how to write an
<computeroutput><command>echo</command></computeroutput> command that
redirects standard output to a file.
When your Bash script is running, it is a process just like any other, so
it also has these three standard I/O streams. The
<computeroutput><command>echo</command></computeroutput> command writes
its output to standard output. Standard output is usually connected to
the terminal on which the script is running, so the output of the
<computeroutput><command>echo</command></computeroutput> command typically
appears on that terminal. It is possible to
<firstterm>redirect</firstterm> an I/O stream so that it is not connected
to the terminal but to a file. <xref linkend="ex-redirect-stdout"/> shows
show you can change the <filename>hello</filename> script to redirect the
standard output of the echo command to a file named
<filename>xyz</filename>.
</para>
<para>
@ -751,24 +886,28 @@ echo Hello world &gt; xyz</programlisting>
</para>
<para>
In this example, the "<computeroutput>> xyz</computeroutput>" at the end of
the "<computeroutput>echo Hello world</computeroutput>" command tells Bash
to temporarilly redirect the script's standard output stream from its
current destination (the terminal) to the file "<filename>xyz</filename>"
for the duration of the
<computeroutput><command>echo</command></computeroutput> command. You can
specify any relative or absolute pathname after the
"<computeroutput>&gt;</computeroutput>".
In this example, the "<computeroutput>&gt;</computeroutput>" is a
<firstterm>metacharacter</firstterm>, which is a character that is not
strictly part of the command to be executed but instead has special
meaning to Bash. The metacharacter
"<computeroutput>&gt;</computeroutput>" tells Bash to temporarilly
redirect standard output of the current command from its current
destination (the terminal) to the specified file for the duration of the
command. You can specify any relative or absolute pathname after the
"<computeroutput>&gt;</computeroutput>". In this example, the output of
the "<computeroutput><command>echo Hello world</command></computeroutput>"
command is redirected to the file <filename>xyz</filename> in the current
working directory.
</para>
<warning>
<title>Warning!</title>
<para>
If the file specified in the output redirection already exists, it is
overwritten, destroying the previous contents of the file! Always be sure
that you don't have any valuable data in the file that is going to be
overwritten by output redirection.
If you redirect standard output to a file that already exists, it is
overwritten, destroying the previous contents of the file! Always be
sure that you don't have any valuable data in the file that is going to
be overwritten by redirection.
</para>
</warning>
@ -859,7 +998,7 @@ echo Hello world &gt; xyz</programlisting>
<title>The <computeroutput>&amp;&amp;</computeroutput> Operator</title>
</sect2>
<sect2 id="sect-andand">
<sect2 id="sect-oror">
<title>The <computeroutput>||</computeroutput> Operator</title>
</sect2>