Reworked several paragraphs. No new material. Still not ready for publication.

This commit is contained in:
franl 2002-11-26 17:08:28 +00:00
parent 441c80818c
commit c973d4cb22
1 changed files with 96 additions and 95 deletions

View File

@ -2,13 +2,13 @@
<!--
IMPORTANT! Before doing any CVS commits, change the DTD from this:
file:/cygdrive/c/franl/doc/docbook-xml-4.2-dtd/docbookx.dtd
to this:
http://docbook.org/xml/4.2/docbookx.dtd
"file:/cygdrive/c/franl/doc/docbook-xml-4.2-dtd/docbookx.dtd"
to:
"http://docbook.org/xml/4.2/docbookx.dtd"
-->
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://docbook.org/xml/4.2/docbookx.dtd"
"http://docbook.org/xml/4.2/docbookx.dtd"
[
<!ENTITY ldp "Linux Documentation Project">
<!ENTITY ldpurl "http://www.tldp.org/">
@ -105,9 +105,9 @@
The Bourne Again Shell (Bash) is the primary shell of the GNU system. It
is compatible with the Bourne shell, which is one of the oldest UNIX
shells, but it has many enhancements that make it superior to the Bourne
shell for scripting. A Bash <firstterm>script</firstterm> is a
human-readable file containing commands that are executed by Bash. This
HOWTO is an introduction to writing Bash scripts.
shell. A Bash <firstterm>script</firstterm> is a human-readable file
containing commands that are executed by Bash. This HOWTO is an
introduction to writing Bash scripts.
</para>
<para>
@ -159,7 +159,7 @@
<title>Feedback</title>
<para>
Feedback is welcome. Send your comments and/or criticisms to the author.
Feedback is welcome. Send your comments to the author.
</para>
</sect2>
@ -341,7 +341,7 @@ echo Hello world</programlisting>
<para>
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
<filename>hello</filename>, and it exists in your current working
directory. <xref linkend="ex-running-hello"/> shows how to execute the
script. In this example, the interactive shell's prompt is shown as
"<computeroutput>bash$</computeroutput>". Your shell's prompt might look
@ -374,23 +374,25 @@ Hello world</screen>
<para>
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>
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 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.
passes it one argument: the name of the file containing the script to
execute. While 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. The interactive
shell isn't doing anything while the script is running &ndash; it's merely
waiting for the non-interactive shell to terminate. In <xref
linkend="ex-running-hello"/>, the 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.
</para>
<para>
It's a bit of a hassle to run Bash scripts this way. It would be simpler
if you could just type the name of your script without the leading
"<computeroutput>bash</computeroutput>" and have the operating system
"<computeroutput>bash</computeroutput>" to make the operating system
automatically start a new Bash shell to execute your script. That way,
the script can be run just like any other program, even programs written
in so-called "real" programming languages, such as C or C++. To allow
@ -407,7 +409,9 @@ Hello world</screen>
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.
allows everyone to execute your script. See the man page for the
<computeroutput><command>chmod</command></computeroutput> command for
more information.
</para>
</listitem>
@ -430,9 +434,7 @@ Hello world</screen>
<para>
Create a directory named "<filename>bin</filename>" under your home
directory. You can do this with the command
"<computeroutput><command>mkdir&nbsp;$HOME/bin</command></computeroutput>"
or
"<computeroutput><command>cd;&nbsp;mkdir&nbsp;bin</command></computeroutput>".
"<computeroutput><command>mkdir&nbsp;$HOME/bin</command></computeroutput>".
</para>
</listitem>
@ -446,12 +448,12 @@ Hello world</screen>
<listitem>
<para>
List the full pathname of that "<filename>bin</filename>" directory in
the value of your <envar>PATH</envar> environment variable (We cover
variables in more detail in <xref linkend="sect-variables"/>). You
can do this by putting the following line into your interactive Bash
startup script (which is the file <filename>.bashrc</filename> in your
home directory):
List the full pathname of that directory in the value of your
<envar>PATH</envar> environment variable (We cover variables in more
detail in <xref linkend="sect-variables"/>). You can do this by
putting the following line into your interactive Bash startup script
(which is the file <filename>.bashrc</filename> in your home
directory):
<blockquote>
<computeroutput>PATH="$HOME/bin:$PATH"</computeroutput>
@ -489,8 +491,8 @@ bash$ <command>chmod u+x hello</command>
bash$ <command>./hello</command>
Hello world
bash$ <command>mkdir $HOME/bin</command>
bash$ <command>PATH="$HOME/bin:$PATH"</command>
bash$ <command>mv hello $HOME/bin</command>
bash$ <command>PATH="$HOME/bin:$PATH"</command>
bash$ <command>hello</command>
Hello world</screen>
</example>
@ -518,12 +520,12 @@ Hello world</screen>
Let's understand how the script shown in <xref linkend="ex-hello-script"/>
works. It's just two lines long, but both lines are significant. Neither
line can be left out. The first line
("<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
<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
(<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
<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.
</para>
@ -550,7 +552,7 @@ Hello world</screen>
<computeroutput><command>echo</command></computeroutput> command is the
general purpose mechanism for producing output. It simply outputs its
arguments to the terminal on which the script is running. A single space
is output betwen each argument.
is output betwen each argument, and a newline character is appended.
</para>
<para>
@ -561,7 +563,7 @@ Hello world</screen>
linkend="sect-interactive-vs-noninteractive"/> for a short list of
exceptions to this rule). But what about that
<emphasis>shebang</emphasis> line
("<computeroutput>#!/bin/bash</computeroutput>")? What happens when Bash
(<computeroutput>#!/bin/bash</computeroutput>)? What happens when Bash
reads and executes that line?
</para>
@ -569,7 +571,7 @@ Hello world</screen>
The answer is: nothing. The text between a
"<computeroutput>#</computeroutput>" character and the end of the same
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 Bash. You should use comments to make your script more readable
by including information that helps the reader understand your script.
We cover comments in more detail in <xref linkend="sect-comments"/>.
</para>
@ -579,7 +581,8 @@ Hello world</screen>
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
script to determine which shell to spawn to interpret the script. Thus,
the first line of a Bash script cannot be omitted, even though it is
the first line of the Bash script shown in <xref
linkend="ex-hello-script"/> cannot be omitted, even though it is
ignored by Bash.
</para>
@ -624,11 +627,11 @@ Hello world</screen>
<computeroutput><command>fg</command></computeroutput>, and
<computeroutput><command>jobs</command></computeroutput> commands to
examine and manipulate the background job. You also cannot use the
"<computeroutput><command>kill %JOBID</command></computeroutput>" form of
the <computeroutput><command>kill</command></computeroutput> command
to kill background jobs. This is not a great loss, since the job
control commands were designed for use in an interactive shell, and
they don't make much sense in a script.
"<computeroutput><command>kill %JOBID</command></computeroutput>" form
of the <computeroutput><command>kill</command></computeroutput>
command to kill background jobs. This is not a great loss, since the
job control commands were designed for interactive use, and they don't
make much sense in a script.
</para>
</listitem>
@ -662,12 +665,12 @@ Hello world</screen>
<para>
A comment is any text following a "<computeroutput>#</computeroutput>"
character on the same line, but the "<computeroutput>#</computeroutput>"
character must be the first character in a word. A Bash script should
contain comments. Comments are ignored by Bash, but they help the person
who reads the script to understand it. <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.
character must be the first character in a word. Comments are ignored by
Bash, but they help the person who reads the script to understand it.
<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>
<para>
@ -722,8 +725,7 @@ Hello</screen>
Professional software engineers know this is not true. Software is hard
to understand if you are not the author. Even if you are the author, it
can be hard to understand long afterwards, when it isn't fresh in your
mind. Between 20% and 50% of the content of your scripts should be
comments.
mind. 20% to 50% of the lines in your scripts should be comments.
</para>
</sect2>
</sect1>
@ -760,10 +762,10 @@ Hello</screen>
<para>
The double quote (<computeroutput>"</computeroutput>) character is the
simplest of the quoting characters. It is used to group 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:
simplest of the quoting characters. It is most commonly used to group
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>
<para>
@ -775,12 +777,12 @@ cat "meeting agenda.txt"</programlisting>
<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> program will be
passed a single filename, <computeroutput>meeting
agenda.txt</computeroutput>. Had the double quotes been omitted, the
<computeroutput><command>cat</command></computeroutput> command would have
been passed two filenames, <filename>meeting</filename> and
<filename>agenda.txt</filename>, which is not what the user intended.
It's important to understand that the
<filename>agenda.txt</filename>. It's important to understand that the
<computeroutput><command>cat</command></computeroutput> program receives
this single argument:
</para>
@ -793,10 +795,11 @@ cat "meeting agenda.txt"</programlisting>
<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 not ignored by Bash. In the above
<computeroutput><command>cat</command></computeroutput> receives, but
there are double quotes in the command. Quote characters are
<firstterm>metacharacters</firstterm>, which means they are removed by
Bash before the command is executed. Even though metacharacters are
removed, they are not ignored by Bash. In the above
<computeroutput><command>cat</command></computeroutput> command, the
double quotes change how Bash passes the arguments to the program, even
though the <computeroutput><command>cat</command></computeroutput> program
@ -807,8 +810,8 @@ cat "meeting agenda.txt"</programlisting>
Double quotes (and their cousins, single quotes and backquotes) must occur
in pairs within a command. Unfortunately, if you accidentally use an odd
number of double quotes in a command, Bash will not report an error. This
is because you can use double quotes to group words that span a newline
character. Try this command in your interactive shell:
happens because you can use double quotes to group words that span a
newline character. Try this command in your interactive shell:
</para>
<para>
@ -824,10 +827,10 @@ two lines"</programlisting>
of that command, your interactive shell doesn't execute the command.
Instead, it notices that you have not typed a closing double quote, and
prompts you to continue entering the command. Only when a complete
command (with a balanced set of double quotes) has been entered, will
pressing the <keysym>ENTER</keysym> key execute the command. You can
write the above command in a shell script too, and it will behave the same
way.
command &ndash; with a balanced set of double quotes &ndash; has been
entered, will pressing the <keysym>ENTER</keysym> key execute the command.
You can write the above command in a shell script too, and it will behave
the same way.
</para>
<para>
@ -885,14 +888,15 @@ echo "*"</programlisting>
<para>
From now on, we'll use the more technical term
<firstterm>escape</firstterm> instead of <firstterm>quote</firstterm> to
refer to using a metacharacter that removes the special meaning of another
metacharacter. Let's be clear about exactly what double quotes do.
Double quotes escape the following Bash metacharacters.
mean using one metacharacter to remove the special meaning of another
metacharacter. Let's be clear exactly which metacharacters double quotes
escape. Double quotes escape the following Bash metacharacters.
</para>
<itemizedlist>
<listitem>
Wildcard characters: <computeroutput>* ? [...]</computeroutput>
Wildcard characters: <computeroutput>* ?
[</computeroutput>...<computeroutput>]</computeroutput>
</listitem>
<listitem>
@ -904,7 +908,7 @@ echo "*"</programlisting>
</listitem>
<listitem>
Background job creation character: <computeroutput>&amp;</computeroutput>
The background job creation character: <computeroutput>&amp;</computeroutput>
</listitem>
<listitem>
@ -934,13 +938,13 @@ echo Now type "start-backup".</programlisting>
</para>
<para>
Try the above command in an interactive Bash shell. The double quotes
do not appear, because Bash removes them before executing the
Try the above command in an interactive Bash shell. The double quotes do
not appear, because Bash removes them before executing the
<computeroutput><command>echo</command></computeroutput> command.
Instead, you must escape the double quotes. That is, you must make Bash
treat the double quote characters as if they are ordinary characters and
not metacharacters. You might think that you can use double quotes to
escape the double quotes, but this doesn't work:
not metacharacters. You cannot use double quotes to escape the double
quotes, like this:
</para>
<para>
@ -1199,25 +1203,22 @@ echo Hello world &gt; xyz</programlisting>
<para>
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.
metacharacter. The "<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 you redirect standard output to a file that already exists, it is
overwritten, destroying the previous contents of the file! Always be
If you redirect standard output to a file that already exists, the file
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>