This commit is contained in:
gferg 2006-05-19 16:11:49 +00:00
parent 1c1d88e52c
commit 32b5c22ea3
12 changed files with 521 additions and 119 deletions

View File

@ -6,6 +6,77 @@
http://personal.riverusers.com/~thegrendel/Change.log
------------------------------------------------------------------------
Version 3.9
Spiceberry release, 05/15/06
1) In the "Starting Off With a Sha-Bang" chapter:
Added footnote that when launching a script from Bash,
the #! isn't strictly necessary.
(Thank you, Diane Holt, for bringing this to my attention.)
2) In "I/O Redirection" chapter:
At introduction to chapter,
Added explanatory examples in introductory in-line code block.
At "Using Exec" section,
Added brief explanation of different effects of "exec N > filename" and "N > filename."
(Thank you, Ahmed Darwish, for both of the above.)
3) In "Special Characters" chapter:
At "$" entry, added an additional usage example.
At "$$" entry, added footnote explaining of what a PID is.
At redirection operators entry, added "<>" description.
At "-" entry, fixup on "bunzip2" example.
(Thanks, Roman.)
4) In "Miscellaneous Commands" section of "External Commands" chapter:
At "yes" entry,
added parsing of variables.
5) In "File and Archiving Commands" section of "External Commands" Chapter:
At "gzip" entry, added note about "-c" option.
6) In "Manipulating Strings" section of "Variables Revisited" chapter:
At "${string%%substring}" entry,
added "ra2ogg.sh" example script.
7) In "Bash, version 3" section of "Bash, versions 2 and 3" chapter
Added "Bash, version 3.1" subsection.
Entry for "+=" operator.
8) In "Subshells" chapter:
Modified final note about command list within curly brackets,
per suggestion of Andreas Kühne.
9) In "Gotchas" chapter:
Converted separate entries to bulleted-item list.
Added entry for error in leaving out termination semicolon in command
block within curly braces.
(Thank you, Andreas Kühne.)
10) In "Writing Scripts" section of "Exercises" appendix:
Added "Checking whether a process is still running" exercise
("Easy" section).
11) "System and Administrative Commands" chapter:
Minor revision of "strace" entry.
Added "ltrace" entry.
Added "lspci" entry.
12) In "Contributed Scripts" appendix:
Minor modification to "life.sh" script, to check for missing startfile.
13) In "Reference Cards" appendix:
Fixed up error in "Miscellaneous Constructs" table (terminating
semicolon in command list within curly brackets).
(Thank you, Andreas Kühne.)
14) In "Revision History" appendix:
Fixed embarrassing typos.
15) Various minor fixups on example scripts.
Version 3.8
Blaeberry release, 02/26/06

View File

@ -43,7 +43,7 @@ prepend.sh (lines 18 and 28)
array-assign.bash
cdll (lines 51-53, 59, 63-69, 82-83, 85, 463, 521, 567-568, 570,
580-586, 637, 656-658)
directory-info.sh (lines 273 and 353)
directory-info.sh (lines 36, 166, 273 and 353)
is-spammer.sh (comments on lines 4, 35, and 51)
bashrc (comments on lines 596 and 618)
commentblock.sh (lines 4 and 23)
@ -52,7 +52,6 @@ self-document2.sh (line 8)
dev-tcp.sh (line 14)
archiveweblogs.sh (comment in line 4)
multiple-processes.sh (line 143)
directory-info.sh (lines 36 and 166)
catscripts.sh (lines 12 and 21)
is_spammer.bash (comments on various lines)
iscan.sh (comment in line 10)
@ -62,3 +61,4 @@ hash-example.sh (comment in line 3: < --> &lt;, > --> &gt;)
quote-fetch.sh (comment in line 26: &amp; --> &)
ftpget.sh (comment in line 28)
whx.sh (comment in line 259)
In-line code block at beginning of "I/O Redirection" chapter, line 41.

View File

@ -321,6 +321,7 @@ Uncomment line below to generate index.
<!ENTITY testcgi SYSTEM "test-cgi.sh">
<!ENTITY spawnscr SYSTEM "spawn.sh">
<!ENTITY iscan SYSTEM "iscan.sh">
<!ENTITY ra2ogg SYSTEM "ra2ogg.sh">
<!ENTITY namesdata SYSTEM "names.data">
<!ENTITY hashlib SYSTEM "Hash.lib">
<!ENTITY hashexample SYSTEM "hash-example.sh">
@ -350,19 +351,12 @@ Uncomment line below to generate index.
</affiliation>
</author>
<releaseinfo>3.8</releaseinfo>
<pubdate>26 February 2006</pubdate>
<releaseinfo>3.9</releaseinfo>
<pubdate>15 May 2006</pubdate>
<revhistory>
<revision>
<revnumber>3.6</revnumber>
<date>28 Aug 2005</date>
<authorinitials>mc</authorinitials>
<revremark>'POKEBERRY' release: Bugfix Update.</revremark>
</revision>
<revision>
<revnumber>3.7</revnumber>
<date>23 Oct 2005</date>
@ -377,6 +371,13 @@ Uncomment line below to generate index.
<revremark>'BLAEBERRY' release: Minor Update.</revremark>
</revision>
<revision>
<revnumber>3.9</revnumber>
<date>15 May 2006</date>
<authorinitials>mc</authorinitials>
<revremark>'SPICEBERRY' release: Minor Update.</revremark>
</revision>
</revhistory>
@ -397,7 +398,7 @@ Uncomment line below to generate index.
introduction to programming concepts.</para>
<para><ulink
url="http://personal.riverusers.com/~thegrendel/abs-guide-3.8.tar.bz2">
url="http://personal.riverusers.com/~thegrendel/abs-guide-3.9.tar.bz2">
The latest update of this document</ulink>, as an archived, <link
linkend="bzipref">bzip2-ed</link> <quote>tarball</quote>
including both the SGML source and rendered HTML, may
@ -761,6 +762,11 @@ exit $WHATEVER # Doesn't matter. The script will not exit here.</programlisting
shell directives. The second example, above, requires the
initial <token>#!</token>, since the variable assignment line,
<userinput>lines=50</userinput>, uses a shell-specific construct.
<footnote><para>If Bash is your default shell, then the
<token>#!</token> isn't necessary at the beginning of a script.
However, if launching a script from a different shell, such as
<firstterm>tcsh</firstterm>, then you <emphasis>will</emphasis>
need the <token>#!</token>.</para></footnote>
Note again that <userinput>#!/bin/sh</userinput> invokes the default
shell interpreter, which defaults to <filename>/bin/bash</filename>
on a Linux machine.</para>
@ -1672,7 +1678,7 @@ echo $var2 # 23skidoo</programlisting>
</varlistentry>
<varlistentry>
<term><token>$$</token></term>
<term><anchor id="processidref"><token>$$</token></term>
<indexterm>
<primary>$$</primary>
</indexterm>
@ -1690,8 +1696,15 @@ echo $var2 # 23skidoo</programlisting>
<listitem><formalpara><title>process ID variable</title>
<para>The <link linkend="proccid">$$ variable</link>
holds the <emphasis>process ID</emphasis> of the script in
which it appears.</para>
holds the <emphasis>process ID</emphasis>
<footnote>
<para>A <firstterm>PID</firstterm>, or
<firstterm>process ID</firstterm>, is a number assigned
to a running process. The <emphasis>PID</emphasis>s
of running processes may be viewed with a <link
linkend="ppssref">ps</link> command.</para>
</footnote>
of the script in which it appears.</para>
</formalpara>
</listitem>
@ -1790,11 +1803,12 @@ cp file22.{txt,backup}
<listitem>
<para><anchor id="codeblockref"></para>
<formalpara><title>Block of code [curly brackets]</title>
<para>Also referred to as an <quote>inline group</quote>,
this construct, in effect, creates an anonymous
function. However, unlike a <link
<para>Also referred to as an <firstterm>inline group</firstterm>,
this construct, in effect, creates an <firstterm>anonymous
function</firstterm> (a function without a
name). However, unlike in a <quote>standard</quote> <link
linkend="functionref">function</link>, the variables
in a code block remain visible to the remainder of the
inside a code block remain visible to the remainder of the
script.</para></formalpara>
<para> <screen><prompt>bash$ </prompt><userinput>{ local a;
@ -1974,7 +1988,7 @@ echo ${Array[1]}</programlisting></para>
<varlistentry>
<term><token>></token> <token>&></token> <token>>&</token> <token>>></token> <token><</token></term>
<term><token>></token> <token>&></token> <token>>&</token> <token>>></token> <token>&lt;</token> <token>&lt;&gt;</token></term>
<indexterm>
<primary>></primary>
</indexterm>
@ -2026,10 +2040,17 @@ echo ${Array[1]}</programlisting></para>
to <filename>stderr</filename>.</para>
<para><userinput>scriptname >>filename</userinput> appends
the output of <filename>scriptname</filename>
to file <filename>filename</filename>. If
<filename>filename</filename> does not already exist,
it will be created.</para>
the output of <filename>scriptname</filename>
to file <filename>filename</filename>. If
<filename>filename</filename> does not already exist,
it is created.</para>
<para><userinput>[i]&lt;&gt;filename</userinput>
opens file <filename>filename</filename> for reading
and writing, and assigns <link linkend="fdref">file
descriptor</link> <token>i</token> to it. If
<filename>filename</filename> does not exist, it is
created.</para>
<formalpara><title><link linkend="processsubref">process substitution</link></title>
@ -2429,11 +2450,11 @@ fi</programlisting>
# If there are hidden files in /source/directory.
</programlisting></para>
<para><programlisting>bunzip2 linux-2.6.13.tar.bz2 | tar xvf -
# --uncompress tar file-- | --then pass it to "tar"--
# If "tar" has not been patched to handle "bunzip2",
# this needs to be done in two discrete steps, using a pipe.
# The purpose of the exercise is to unarchive "bzipped" kernel source.
<para><programlisting>bunzip2 -c linux-2.6.16.tar.bz2 | tar xvf -
# --uncompress tar file-- | --then pass it to "tar"--
# If "tar" has not been patched to handle "bunzip2",
#+ this needs to be done in two discrete steps, using a pipe.
# The purpose of the exercise is to unarchive "bzipped" kernel source.
</programlisting></para>
<para>Note that in this context the <quote>-</quote> is not
@ -6456,8 +6477,10 @@ echo "Last command argument processed = $last_cmd_arg"
<para>The <varname>$PPID</varname> of a process is
the process ID (<varname>pid</varname>) of its parent process.
<footnote><para>The PID of the currently running script is
<varname>$$</varname>, of course.</para></footnote>
<footnote>
<para>The PID of the currently running script is
<varname>$$</varname>, of course.</para>
</footnote>
</para>
<para>Compare this with the <link
@ -7551,11 +7574,19 @@ echo ${stringZ%%b*c} # a
# Strip out longest match between 'b' and 'c', from back of $stringZ.</programlisting>
</para>
<para>This operator is useful for generating filenames.</para>
<example id="cvt">
<title>Converting graphic file formats, with filename change</title>
<programlisting>&cvt;</programlisting>
</example>
<example id="ra2ogg">
<title>Converting streaming audio files to
<emphasis>ogg</emphasis></title>
<programlisting>&ra2ogg;</programlisting>
</example>
<para>A simple emulation of <link linkend="getopty">getopt</link>
using substring extraction constructs.</para>
@ -8629,6 +8660,7 @@ echo $? # 1
<para>The argument <replaceable>list</replaceable> may contain wild cards.</para>
<para><anchor id="needsemicolon"></para>
<para>If <firstterm>do</firstterm> is on same line as
<firstterm>for</firstterm>, there needs to be a semicolon
after list.</para>
@ -8816,7 +8848,7 @@ echo $? # 1
</cmdsynopsis></para>
<para>As is the case with <firstterm>for loops</firstterm>,
<para><link linkend="needsemicolon">As is the case with <firstterm>for loops</firstterm></link>,
placing the <firstterm>do</firstterm> on the same line as
the condition test requires a semicolon.</para>
@ -12222,7 +12254,7 @@ OneYearAgo=$(date --date='1 year ago')</programlisting></para>
</varlistentry>
<varlistentry>
<term><command>sleep</command></term>
<term><anchor id="sleepref"><command>sleep</command></term>
<indexterm>
<primary>sleep</primary>
</indexterm>
@ -13886,6 +13918,11 @@ function write_utf8_string {
command is <command>gunzip</command>, which is the equivalent of
<command>gzip -d</command>.</para>
<note><para>The <option>-c</option> option sends the output of
<command>gzip</command> to <filename>stdout</filename>. This
is useful when <link linkend="piperef">piping</link> to other
commands.</para></note>
<para>The <command>zcat</command> filter decompresses a
<emphasis>gzipped</emphasis> file to
<filename>stdout</filename>, as possible input to a pipe or
@ -13895,6 +13932,7 @@ function write_utf8_string {
utility). The <command>zcat</command> command is equivalent to
<command>gzip -dc</command>.</para>
<caution><para>On some commercial UNIX systems, <command>zcat</command>
is a synonym for <command>uncompress -c</command>,
and will not work on <emphasis>gzipped</emphasis>
@ -16325,6 +16363,22 @@ done</programlisting></para>
linkend="fdiskref">fdisk</link>. It may have unintended
side-effects.</para></warning>
<note>
<para>The <command>yes</command> command parses variables.
For example:</para>
<para>
<screen><prompt>bash$ </prompt><userinput>yes $BASH_VERSION</userinput>
<computeroutput>3.00.16(1)-release
3.00.16(1)-release
3.00.16(1)-release
3.00.16(1)-release
3.00.16(1)-release
. . .</computeroutput>
</screen>
</para>
<para>This <quote>feature</quote> may not be particularly useful.</para>
</note>
</listitem>
</varlistentry>
@ -17758,18 +17812,23 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ</programlisting><
</indexterm>
<indexterm>
<primary>command</primary>
<secondary>strace</secondary>
<secondary>trace</secondary>
</indexterm>
<listitem>
<para>Diagnostic and debugging tool for tracing system
calls and signals. The simplest way of invoking it is
<command>strace COMMAND</command>.</para>
<para><command>S</command>ystem <command>trace</command>:
diagnostic and debugging tool for tracing <firstterm>system
calls</firstterm> and signals. This command and
<command>ltrace</command>, following, are useful for
diagnosing why a given program or package fails to
run . . . perhaps due to missing libraries or related
causes.</para>
<para>
<screen><prompt>bash$ </prompt><userinput>strace df</userinput>
<computeroutput>execve("/bin/df", ["df"], [/* 45 vars */]) = 0
uname({sys="Linux", node="bozo.localdomain", ...}) = 0
brk(0) = 0x804f5e4
...</computeroutput>
</screen>
</para>
@ -17780,6 +17839,37 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ</programlisting><
</listitem>
</varlistentry>
<varlistentry>
<term><command>ltrace</command></term>
<indexterm>
<primary>ltrace</primary>
</indexterm>
<indexterm>
<primary>command</primary>
<secondary>trace</secondary>
</indexterm>
<listitem>
<para><command>L</command>ibrary <command>trace</command>:
diagnostic and debugging tool that traces <firstterm>library calls</firstterm>
invoked by a given command.</para>
<para>
<screen><prompt>bash$ </prompt><userinput>ltrace df</userinput>
<computeroutput>__libc_start_main(0x804a910, 1, 0xbfb589a4, 0x804fb70, 0x804fb68 &lt;unfinished ...&gt:
setlocale(6, "") = "en_US.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils") = "coreutils"
__cxa_atexit(0x804b650, 0, 0, 0x8052bf0, 0xbfb58908) = 0
getenv("DF_BLOCK_SIZE") = NULL
...</computeroutput>
</screen>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><anchor id="nmapref"><command>nmap</command></term>
<indexterm>
@ -18370,7 +18460,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26</compute
<title><anchor id="jobcontrolsys1">Job Control</title>
<varlistentry>
<term><command>ps</command></term>
<term><anchor id="ppssref"><command>ps</command></term>
<indexterm>
<primary>ps</primary>
</indexterm>
@ -19364,6 +19454,7 @@ mount -o loop /dev/loop0 /mnt # Mount it.
bMaxPacketSize0 8
idVendor 0x0000
idProduct 0x0000
. . .</computeroutput>
</screen>
</para>
@ -19371,6 +19462,36 @@ mount -o loop /dev/loop0 /mnt # Mount it.
</listitem>
</varlistentry>
<varlistentry>
<term><command>lspci</command></term>
<indexterm>
<primary>lspci</primary>
</indexterm>
<indexterm>
<primary>command</primary>
<secondary>pci</secondary>
</indexterm>
<listitem>
<para>Lists <firstterm>pci</firstterm> busses present.</para>
<para>
<screen><prompt>bash$ </prompt><userinput>lspci</userinput>
<computeroutput>00:00.0 Host bridge: Intel Corporation 82845 845 (Brookdale) Chipset Host Bridge (rev 04)
00:01.0 PCI bridge: Intel Corporation 82845 845 (Brookdale) Chipset AGP Bridge (rev 04)
00:1d.0 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #1) (rev 02)
00:1d.1 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #2) (rev 02)
00:1d.2 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #3) (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev 42)
. . .</computeroutput>
</screen>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>mkbootdisk</command></term>
<indexterm>
@ -20588,17 +20709,26 @@ let "z += 3" # Quotes permit the use of spaces in variable assignment.
# --------------------------------------------------------------------
1>filename
# Redirect stdout to file "filename".
# Redirect stdout to file "filename."
1>>filename
# Redirect and append stdout to file "filename".
# Redirect and append stdout to file "filename."
2>filename
# Redirect stderr to file "filename".
# Redirect stderr to file "filename."
2>>filename
# Redirect and append stderr to file "filename".
# Redirect and append stderr to file "filename."
&>filename
# Redirect both stdout and stderr to file "filename".
# Redirect both stdout and stderr to file "filename."
M>N
# "M" is a file descriptor, which defaults to 1, if not explicitly set.
# "N" is a filename.
# File descriptor "M" is redirect to file "N."
M&gt;&amp;N
# "M" is a file descriptor, which defaults to 1, if not set.
# "N" is another file descriptor.
#==============================================================================
# Redirecting stdout, one line at a time.
LOGFILE=script.log
@ -20773,6 +20903,22 @@ exec 3>&- # Now close it for the remainder of the s
file. This sends all command output that would normally go
to <filename>stdout</filename> to that file.</para>
<important>
<para>
<command>exec N > filename</command> affects the entire
script or <emphasis>current shell</emphasis>. Redirection in
the <link linkend="processidref">PID</link> of the script or shell
from that point on has changed. However . . .
</para>
<para>
<command>N > filename</command> affects only the newly-forked process,
not the entire script or shell.
</para>
<para>Thank you, Ahmed Darwish, for pointing this out.</para>
</important>
<example id="reassignstdout">
<title>Redirecting <filename>stdout</filename> using
<command>exec</command></title>
@ -21191,9 +21337,9 @@ echo "This line had better not echo." # Follows an 'exit' command.</programlist
<para><anchor id="herestringsref"></para>
<para>A <emphasis>here string</emphasis> can be considered as
a stripped-down form of <emphasis>here document</emphasis>. It
consists of nothing more than <command>COMMAND
<para>A <firstterm>here string</firstterm> can be considered as
a stripped-down form of a <firstterm>here document</firstterm>.
It consists of nothing more than <command>COMMAND
&lt;&lt;&lt;$WORD</command>, where <varname>$WORD</varname>
is expanded and fed to the <filename>stdin</filename> of
<varname>COMMAND</varname>.</para>
@ -21455,6 +21601,8 @@ exit 0</programlisting></para></footnote>
<para><anchor id="dollarsignref"></para>
<para>The dollar sign -- <token>$</token> -- at the end of an
RE matches the end of a line.</para>
<para><quote>XXX$</quote> matches <emphasis>XXX</emphasis> at the
end of a line.</para>
<para><quote>^$</quote> matches blank lines.</para>
</listitem>
@ -22246,7 +22394,7 @@ fi
<note><para>A command block between <replaceable>curly
braces</replaceable> does <emphasis>not</emphasis> launch
a subshell.</para>
<para>{ command1; command2; command3; ... }</para></note>
<para>{ command1; command2; command3; . . . commandN; }</para></note>
</chapter> <!-- Subshells -->
@ -24574,7 +24722,14 @@ trap 'echo "Control-C disabled."' 2
<para><anchor id="bash3gotcha"></para>
<para>Assigning reserved words or characters to variable names.
<itemizedlist>
<listitem>
<para>Assigning reserved words or characters to variable names.</para>
<para>
<programlisting>case=value0 # Causes problems.
23skidoo=value1 # Also problems.
# Variable names starting with a digit are reserved by the shell.
@ -24587,9 +24742,12 @@ echo $_ # $_ is a special variable set to last arg of last command.
xyz((!*=value2 # Causes severe problems.
# As of version 3 of Bash, periods are not allowed within variable names.</programlisting>
</para>
</listitem>
<listitem>
<para>Using a hyphen or other reserved characters in a variable name (or
function name).
function name).</para>
<para>
<programlisting>var-1=23
# Use 'var_1' instead.
@ -24601,9 +24759,12 @@ function-whatever () # Error
function.whatever () # Error
# Use 'functionWhatever ()' instead.</programlisting>
</para>
</listitem>
<listitem>
<para>Using the same name for a variable and a function. This can make a
script difficult to understand.
script difficult to understand.</para>
<para>
<programlisting>do_something ()
{
echo "This function does something with \"$1\"."
@ -24615,13 +24776,17 @@ do_something do_something
# All this is legal, but highly confusing.</programlisting>
</para>
</listitem>
<listitem>
<para><anchor id="wsbad">Using <link
linkend="whitespaceref">whitespace</link> inappropriately.
In contrast to other programming languages, Bash can be quite
finicky about whitespace.
finicky about whitespace.</para>
<para>
<programlisting>var1 = 23 # 'var1=23' is correct.
# On line above, Bash attempts to execute command "var1"
# with the arguments "=" and "23".
@ -24632,24 +24797,46 @@ if [ $a -le 5] # if [ $a -le 5 ] is correct.
# if [ "$a" -le 5 ] is even better.
# [[ $a -le 5 ]] also works.</programlisting>
</para>
</listitem>
<listitem>
<para>Not terminating with a <firstterm>semicolon</firstterm> the final
command in a <link linkend="codeblockref">code block within curly
brackets</link>.</para>
<para>
<programlisting>{ ls -l; df; echo "Done." }
# bash: syntax error: unexpected end of file
{ ls -l; df; echo "Done."; }
# ^ ### Final command needs semicolon.</programlisting>
</para>
</listitem>
<listitem>
<para>
Assuming uninitialized variables (variables before a value is
assigned to them) are <quote>zeroed out</quote>. An
uninitialized variable has a value of <quote>null</quote>,
<emphasis>not</emphasis> zero.
<emphasis>not</emphasis> zero.</para>
<para>
<programlisting>#!/bin/bash
echo "uninitialized_var = $uninitialized_var"
# uninitialized_var =</programlisting>
</para>
</listitem>
<listitem>
<para>Mixing up <emphasis>=</emphasis> and <emphasis>-eq</emphasis> in
a test. Remember, <emphasis>=</emphasis> is for comparing literal
variables and <emphasis>-eq</emphasis> for integers.
variables and <emphasis>-eq</emphasis> for integers.</para>
<para>
<programlisting>if [ "$a" = 273 ] # Is $a an integer or string?
if [ "$a" -eq 273 ] # If $a is an integer.
@ -24677,8 +24864,10 @@ then
fi # Aborts with an error message.
# test.sh: [: 273.0: integer expression expected</programlisting>
</para>
</listitem>
<listitem>
<para>Misusing <link linkend="scomparison1">string comparison</link>
operators.</para>
@ -24686,41 +24875,55 @@ fi # Aborts with an error message.
<title>Numerical and string comparison are not equivalent</title>
<programlisting>&badop;</programlisting>
</example>
</listitem>
<listitem>
<para>Sometimes variables within <quote>test</quote> brackets
([ ]) need to be quoted (double quotes). Failure to do so may
cause unexpected behavior. See <xref linkend="strtest">, <xref
linkend="redir2">, and <xref linkend="arglist">.</para>
</listitem>
<listitem>
<para>Commands issued from a script may fail to execute because
the script owner lacks execute permission for them. If a user
cannot invoke a command from the command line, then putting it
into a script will likewise fail. Try changing the attributes of
the command in question, perhaps even setting the suid bit
(as root, of course).</para>
</listitem>
<listitem>
<para>Attempting to use <command>-</command> as a redirection
operator (which it is not) will usually result in an unpleasant
surprise.
surprise.</para>
<para>
<programlisting>command1 2&gt; - | command2 # Trying to redirect error output of command1 into a pipe...
# ...will not work.
command1 2&gt;&amp; - | command2 # Also futile.
Thanks, S.C.</programlisting></para>
</listitem>
<listitem>
<para>Using Bash <link linkend="bash2ref">version 2+</link>
functionality may cause a bailout with error messages. Older
Linux machines may have version 1.XX of Bash as the default
installation.
installation.</para>
<para>
<programlisting>#!/bin/bash
minimum_version=2
# Since Chet Ramey is constantly adding features to Bash,
# you may set $minimum_version to 2.XX, or whatever is appropriate.
# you may set $minimum_version to 2.XX, 3.XX, or whatever is appropriate.
E_BAD_VERSION=80
if [ "$BASH_VERSION" \< "$minimum_version" ]
@ -24731,14 +24934,19 @@ then
fi
...</programlisting></para>
</listitem>
<listitem>
<para>Using Bash-specific functionality in a Bourne shell script
(<userinput>#!/bin/sh</userinput>) on a non-Linux machine
may cause unexpected behavior. A Linux system usually aliases
<command>sh</command> to <command>bash</command>, but this does
not necessarily hold true for a generic UNIX machine.</para>
</listitem>
<listitem>
<para>Using undocumented features in Bash turns out to be a
dangerous practice. In previous releases of this
book there were several scripts that depended on the
@ -24748,13 +24956,18 @@ fi
did not apply to <emphasis>negative</emphasis> integers.
Unfortunately, in version 2.05b and later, that loophole
disappeared. See <xref linkend="returntest">.</para>
</listitem>
<listitem>
<para>
A script with DOS-type newlines (<replaceable>\r\n</replaceable>)
will fail to execute, since <userinput>#!/bin/bash\r\n</userinput>
is not recognized, <emphasis>not</emphasis> the same as the
expected <userinput>#!/bin/bash\n</userinput>. The fix is to
convert the script to UNIX-style newlines.
is <emphasis>not</emphasis> recognized, <emphasis>not</emphasis>
the same as the expected <userinput>#!/bin/bash\n</userinput>. The
fix is to convert the script to UNIX-style newlines.</para>
<para>
<programlisting>#!/bin/bash
echo "Here"
@ -24771,24 +24984,34 @@ echo "There"
exit 0</programlisting>
</para>
</listitem>
<listitem>
<para>A shell script headed by <userinput>#!/bin/sh</userinput>
will not run in full Bash-compatibility mode. Some Bash-specific
functions might be disabled. Scripts that need complete
access to all the Bash-specific extensions should start with
<userinput>#!/bin/bash</userinput>.</para>
</listitem>
<listitem>
<para><link linkend="indentedls">Putting whitespace in front of
the terminating limit string</link> of a <link
linkend="heredocref">here document</link> will cause unexpected
behavior in a script.</para>
</listitem>
<listitem>
<para><anchor id="parchildprobref"></para>
<para>A script may not <command>export</command> variables back
to its <link linkend="forkref">parent process</link>, the shell,
or to the environment. Just as we learned in biology, a child
process can inherit from a parent, but not vice versa.
process can inherit from a parent, but not vice versa.</para>
<para>
<programlisting>WHATEVER=/home/bozo
export WHATEVER
exit 0</programlisting>
@ -24797,9 +25020,16 @@ exit 0</programlisting>
</computeroutput>
<prompt>bash$ </prompt></screen>
Sure enough, back at the command prompt, $WHATEVER remains unset.
</para>
</para>
<para>
Sure enough, back at the command prompt, $WHATEVER remains unset.
</para>
</listitem>
<listitem>
<para>Setting and manipulating variables in a <link
linkend="subshellsref">subshell</link>, then attempting
to use those same variables outside the scope of the subshell will
@ -24809,7 +25039,11 @@ exit 0</programlisting>
<title>Subshell Pitfalls</title>
<programlisting>&subpit;</programlisting>
</example>
</listitem>
<listitem>
<para><anchor id="badread0"></para>
<para><link linkend="piperef">Piping</link>
<command>echo</command> output to a <link
@ -24899,32 +25133,44 @@ find $HOME -type f -atime +30 -size 100k | {
<programlisting>tail -f /var/log/messages | grep "$ERROR_MSG" >> error.log
# The "error.log" file will not have anything written to it.</programlisting>
</para>
</listitem>
<para>--</para>
<listitem>
<para>Using <quote>suid</quote> commands within scripts is risky,
as it may compromise system security.
<footnote><para>Setting the <emphasis>suid</emphasis> permission on
the script itself has no effect.</para></footnote>
</para>
</listitem>
<listitem>
<para>Using shell scripts for CGI programming may be problematic. Shell
script variables are not <quote>typesafe</quote>, and this can cause
undesirable behavior as far as CGI is concerned. Moreover, it is
difficult to <quote>cracker-proof</quote> shell scripts.</para>
</listitem>
<listitem>
<para>Bash does not handle the <link linkend="doubleslashref">double slash
(<token>//</token>) string</link> correctly.</para>
</listitem>
<listitem>
<para>Bash scripts written for Linux or BSD systems may need
fixups to run on a commercial UNIX (or Apple OSX) machine. Such
scripts often employ GNU commands and filters which have greater
functionality than their generic UNIX counterparts. This is
particularly true of such text processing utilites as <link
linkend="trref">tr</link>.</para>
</listitem>
</itemizedlist>
<epigraph>
<attribution>A.J. Lamb and H.W. Petrie</attribution>
@ -26563,6 +26809,51 @@ fi</programlisting></para>
</caution>
<sect2> <!-- Bash, Version 3.1 -->
<title>Bash, version 3.1</title>
<para>The version 3.1 update of Bash introduces a number of bugfixes
and a few minor changes.</para>
<itemizedlist>
<listitem>
<para>The <token>+=</token> operator is now permitted in
in places where previously only the <token>=</token>
assignment operator was recognized.</para>
<para><programlisting>a=1
echo $a # 1
a+=5 # Won't work under versions of Bash earlier than 3.1.
echo $a # 15
a+=Hello
echo $a # 15Hello</programlisting>
</para>
<para>Here, <token>+=</token> functions as a <firstterm>string
concatenation</firstterm> operator. Note that its behavior
in this particular context is different than within a
<link linkend="letref">let</link> construct.</para>
<para><programlisting>a=1
echo $a # 1
let a+=5 # Integer arithmetic, rather than string concatenation.
echo $a # 6
let a+=Hello # Doesn't "add" anything to a.
echo $a # 6</programlisting>
</para>
</listitem>
</itemizedlist>
</sect2> <!-- Bash, Version 3 -->
</sect1> <!-- Bash, Version 3 -->
</chapter> <!-- Bash, versions 2 and 3 -->
@ -26861,7 +27152,8 @@ fi</programlisting></para>
Chris Morgan, Walter Dnes, Linc Fessenden, Michael Iatrou, Pharis
Monalo, Jesse Gough, Fabian Kreutz, Mark Norman, Harald Koenig,
Peter Knowles, Francisco Lobo, Mariusz Gniazdowski, Tedman Eng,
and David Lawyer (himself an author of four HOWTOs).</para>
Achmed Darwish, Andreas K&uuml;hne, and David Lawyer (himself
an author of four HOWTOs).</para>
<para>My gratitude to <ulink url="mailto:chet@po.cwru.edu">Chet
Ramey</ulink> and Brian Fox for writing <firstterm>Bash</firstterm>,
@ -28523,7 +28815,7 @@ fi</programlisting></para>
<entry><link linkend="ivrref">Indirect variable reference</link></entry>
</row>
<row>
<entry><option>{ command1; command2 }</option></entry>
<entry><option>{ command1; command2; . . . commandN; }</option></entry>
<entry>Block of code</entry>
</row>
<row>
@ -30629,6 +30921,18 @@ done < `tail -f /var/log/messages`</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term><command>Checking whether a process is still running</command></term>
<listitem>
<para>Given a <link linkend="processidref">process ID</link>
(<firstterm>PID</firstterm>) as an argument, this script
will check, at user-specified intervals, whether
the given process is still running. You may use
the <link linkend="ppssref">ps</link> and <link
linkend="sleepref">sleep</link> commands.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>Primes</command></term>
<listitem>
@ -31351,7 +31655,7 @@ fairly detailed rundown on the Playfair Cipher and its solution methods.</progra
<title>Revision History</title>
<synopsis>
This document first appeared as a HOWTO in the late spring
This document first appeared as a 60-page HOWTO in the late spring
of 2000. Since then, it has gone through quite a number of
updates and revisions. This book could not have been written
without the assistance of the Linux community, and especially
@ -31527,22 +31831,27 @@ fairly detailed rundown on the Playfair Cipher and its solution methods.</progra
<row>
<entry><option>3.5</option></entry>
<entry>05 Jun 2005</entry>
<entry>BOXBERRY release: Bugfixes, some materials added.</entry>
<entry>BOXBERRY release: Bugfixes, some material added.</entry>
</row>
<row>
<entry><option>3.6</option></entry>
<entry>28 Aug 2005</entry>
<entry>POKEBERRY release: Bugfixes, some materials added.</entry>
<entry>POKEBERRY release: Bugfixes, some material added.</entry>
</row>
<row>
<entry><option>3.7</option></entry>
<entry>23 Oct 2005</entry>
<entry>WHORTLEBERRY release: Bugfixes, some materials added.</entry>
<entry>WHORTLEBERRY release: Bugfixes, some material added.</entry>
</row>
<row>
<entry><option>3.8</option></entry>
<entry>26 Feb 2006</entry>
<entry>BLAEBERRY release: Bugfixes, some materials added.</entry>
<entry>BLAEBERRY release: Bugfixes, some material added.</entry>
</row>
<row>
<entry><option>3.9</option></entry>
<entry>15 May 2006</entry>
<entry>SPICEBERRY release: Bugfixes, some material added.</entry>
</row>
</tbody>
</tgroup>
@ -31555,7 +31864,7 @@ fairly detailed rundown on the Playfair Cipher and its solution methods.</progra
<title>Mirror Sites</title>
<para><ulink
url="http://personal.riverusers.com/~thegrendel/abs-guide-3.7.tar.bz2">
url="http://thegrendel.150m.com/abs-guide-3.9.tar.bz2">
The latest update of this document</ulink>, as an archived
<quote>tarball</quote>
including both the SGML source and rendered HTML, may

View File

@ -65,7 +65,7 @@ do
then
exchange $index `expr $index + 1` # Swap.
fi
let "index += 1"
let "index += 1" # Or, index+=1 on Bash, ver. 3.1 or newer.
done # End of inner loop
# ----------------------------------------------------------------------

View File

@ -28,6 +28,9 @@ while [ "$index" -lt "$element_count" ]
do # List all the elements in the array.
echo ${colors[$index]}
let "index = $index + 1"
# Or:
# index+=1
# if running Bash, version 3.1 or later.
done
# Each array element listed on a separate line.
# If this is not desired, use echo -n "${colors[$index]} "

View File

@ -13,7 +13,7 @@
#+ The gcd = dividend, on the final pass.
#
# For an excellent discussion of Euclid's algorithm, see
# Jim Loy's site, http://www.jimloy.com/number/euclids.htm.
#+ Jim Loy's site, http://www.jimloy.com/number/euclids.htm.
# ------------------------------------------------------
@ -33,7 +33,7 @@ gcd ()
{
dividend=$1 # Arbitrary assignment.
divisor=$2 #+ It doesn't matter which of the two is larger.
divisor=$2 #! It doesn't matter which of the two is larger.
# Why not?
remainder=1 # If uninitialized variable used in loop,

View File

@ -31,12 +31,23 @@ startfile=gen0 # Read the starting generation from the file "gen0".
#
if [ -n "$1" ] # Specify another "generation 0" file.
then
if [ -e "$1" ] # Check for existence.
then
startfile="$1"
fi
fi
############################################
# Abort script if "startfile" not specified
#+ AND
#+ "gen0" not present.
E_NOSTARTFILE=68
if [ ! -e "$startfile" ]
then
echo "Startfile \""$startfile"\" missing!"
exit $E_NOSTARTFILE
fi
############################################
ALIVE1=.
DEAD1=_
@ -337,9 +348,9 @@ done
echo
exit 0
exit 0 # END
# --------------------------------------------------------------
# The grid in this script has a "boundary problem."
# The the top, bottom, and sides border on a void of dead cells.

View File

@ -9,7 +9,7 @@
# The first 20 terms of the series are:
# 1 1 2 3 3 4 5 5 6 6 6 8 8 8 10 9 10 11 11 12
# See Hofstadter's book, "Goedel, Escher, Bach: An Eternal Golden Braid",
# See Hofstadter's book, _Goedel, Escher, Bach: An Eternal Golden Braid_,
#+ p. 137, ff.

View File

@ -2181,7 +2181,7 @@ This HOWTO has been removed for review. </Para>
Linksys-Blue-Box-Router-HOWTO</ULink>,
<CiteTitle>Linksys Blue Box Router HOWTO</CiteTitle>
</Para><Para>
<CiteTitle>Updated: Dec 2005</CiteTitle>.
<CiteTitle>Updated: May 2006</CiteTitle>.
Hints and tips for managing Linksys
routers from a Linux system, including the firmware upgrade procedure. </Para>
</ListItem>

View File

@ -1078,7 +1078,7 @@ scanner device on a system running Linux. </Para>
Linksys-Blue-Box-Router-HOWTO</ULink>,
<CiteTitle>Linksys Blue Box Router HOWTO</CiteTitle>
</Para><Para>
<CiteTitle>Updated: Dec 2005</CiteTitle>.
<CiteTitle>Updated: May 2006</CiteTitle>.
Hints and tips for managing Linksys
routers from a Linux system, including the firmware upgrade procedure. </Para>
</ListItem>

View File

@ -937,7 +937,7 @@ How to enable the Linux IP Masquerade feature on a given Linux host. </Para>
Linksys-Blue-Box-Router-HOWTO</ULink>,
<CiteTitle>Linksys Blue Box Router HOWTO</CiteTitle>
</Para><Para>
<CiteTitle>Updated: Dec 2005</CiteTitle>.
<CiteTitle>Updated: May 2006</CiteTitle>.
Hints and tips for managing Linksys
routers from a Linux system, including the firmware upgrade procedure. </Para>
</ListItem>

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://docbook.org/xml/4.2/docbookx.dtd" [
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY howto "http://www.tldp.org/HOWTO/">
<!ENTITY mini-howto "http://www.tldp.org/HOWTO/mini/">
<!ENTITY home "http://www.catb.org/~esr/">
@ -20,6 +20,15 @@
</author>
<revhistory>
<revision>
<revnumber>2.3</revnumber>
<date>2006-05-19</date>
<authorinitials>esr</authorinitials>
<revremark>
Revised the list of open firmware distributions, and other minor
corrections.
</revremark>
</revision>
<revision>
<revnumber>2.2</revnumber>
<date>2005-12-01</date>
@ -149,7 +158,7 @@ machine over a cable.</para>
<para>Also note that if you go looking for one of these now, be sure to get
the WRT54GL &mdash; note the L suffix. At Version 5 and up, the vanilla
WRT54G is different hardware with less RAM that runs a propriatary
WRT54G is different hardware with less RAM that runs a proprietary
VxWorks OS.</para>
</sect2>
@ -184,9 +193,7 @@ ignore you.</para>
to be used as gateway boxes on a home Ethernet. Typically, you'll hook one
up to a DSL or cable modem, which will automatically switch into bridge
mode and simply pass packets between your ISP's router and the Linksys box.
Here's a <ulink
url='http://www.linksys.com/products/group.asp?grid=33&amp;scid=35'>recognition
chart</ulink> of these products.</para>
</para>
<para>If you want to use a general-purpose PC running Linux as a firewall,
have fun &mdash; but these little boxes are more efficient. The nicest
@ -202,9 +209,9 @@ year, and I heard grumbling from others about similar problems.
Unfortunately when I tried other low-end brands (Belkin, Buffalo) they
proved to have gross design errors. The Belkin had brain-damage in its
firewall rules that interfered with local SMTP, and the Buffalo
intermittently refused connections for no apparent reason. So I'm back
with Linksys. hoping my WRT54G doesn't turn into a doorstop within a couple
of months.</para>
intermittently refused connections for no apparent reason. So I went back
with Linksys, hoping my WRT54G wouldn't turn into a doorstop within a couple
of months. As of mid-2006, I've been OK for about 24 months.</para>
<para>(Building one of these puppies is not rocket science. I can only
conjecture that the competitive pressure is driving the manufacturers to cut
@ -218,8 +225,8 @@ what marketers call a flank guard, a low-end brand designed to protect the
margins and brand image of Cisco's commercial-grade networking products.
This means that Linksys boxes are no longer acquiring new firmware
features, and some old ones like stateful packet inspection almost
certainly won't be coming back. Provided you can live wthin these limits,
this is actually good; simpler firmware is stable firmware.</para>
certainly won't be coming back. Provided you can live within these limits,
this is actually good; simpler firmware is more stable firmware.</para>
<para>At minimum, a live Linksys box will do the following things for
you:</para>
@ -260,7 +267,7 @@ built into the firmware, a good thing if your net connection is
down.</para>
<para>Unfortunately, you're in trouble if you have to bring in Linksys tech
support. On the one occasion that I called them, the first tech
support. On the one occasion that I called them (in 2003), the first tech
I raised couldn't even speak English, and the second was barely competent
at it. Both were complete and utter idiots whose response to any
nontrivial question was to put me on infinite hold while they went
@ -285,8 +292,7 @@ reported</ulink> that turning off the remote admin feature doesn't work
side. This bug is still present in the 2.02 firmware, October 2004. It
means that if you leave your password at default, any script kiddie can
break in, steal your WEP, and scramble your configuration. The Linksys
people get the moron medal with oak-leaf cluster for this
screwup.</para>
people get the moron medal with oak-leaf cluster for this screwup.</para>
<para>(I don't know if this bug is still present in the 3.x firmware. It
would be a good idea to check.)</para>
@ -321,7 +327,7 @@ network.</para></step>
</procedure>
<para>There are two more steps for older firmware versions only. You can
ignore these if you have 2.x firmware.</para>
ignore these if you have 2.x or later firmware.</para>
<procedure>
<step><para><emphasis role='bold'>Disable AOL Parental Controls.</emphasis>
@ -365,9 +371,9 @@ WINE. Not recommended.</para>
<para>The third way is to use <application>tftp</application>. This is how
I did it the first time, before Linksys added the <quote>Upgrade
firmware</quote> to the firmware, and I document it here for completeness
even though I now recommend that method. There is a tftp client included
with Red Hat Linux. To upgrade your firmware this way, do the following
steps:</para>
even though I now recommend their upgrade method. There is a tftp client
included with Red Hat Linux. To upgrade your firmware this way, do the
following steps:</para>
<procedure>
<step>
@ -378,9 +384,7 @@ your basic settings but clear some advanced ones.</para>
</step>
<step>
<para><emphasis role='bold'>Download a copy of the new firmware.</emphasis>
You should find it at <ulink
url="http://www.linksys.com/download/firmware.asp?dlid=1"> Firmware
Upgrades for your Linksys Products</ulink> on the Linksys site. Note that
Follow the Downloads link from the Linkys main page. Note that
what you get may well be marked <quote>For Windows Users</quote> and be a
zip archive. Open it in a scratch directory, because it will rudely create
several Windows files wherever you unpack it. The file you need will be
@ -395,9 +399,9 @@ until both the Password and Confirm fields are blank, and click
Apply.</para>
</step>
<step>
<para><emphasis role='bold'>Cross your fingers and load the firmware.</emphasis>
The command session you want will to see will look something like
this, with your router's IP address substituted for
<para><emphasis role='bold'>Cross your fingers and load the
firmware.</emphasis> The command session you want will to see will look
something like this, with your router's IP address substituted for
192.168.1.1:</para>
<screen>
@ -425,11 +429,7 @@ the firmware version number will have changed.</para>
</sect1>
<sect1><title>Hacking the hardware</title>
<para>There is a <ulink
url="http://www.bextreme.net/wap11web/">page</ulink> that tells you how to
casemod the Linksys WAP11 wireless access point.</para>
<para>Linksys boxes have firmware support for a serial console, The circuit
<para>Linksys boxes have firmware support for a serial console. The circuit
board has traces for two serial ports, but you have to do some fairly
serious modding to get them working. <ulink
url="http://www.rwhitby.net/wrt54gs/serial.html">This page</ulink> will
@ -438,12 +438,12 @@ show you how.</para>
</sect1>
<sect1><title>Hacking the software</title>
<para>Linxsys routers run Linux from firmware. Linksys supplies <ulink
url="http://www.linksys.com/support/gpl.asp">source code</ulink> on its
site.</para>
<para>Linksys routers run Linux from firmware. Linksys supplies source
code on its site; look for "GPL Code Center" under technical
support.</para>
<para>There are several replacements for the WRT54G firmware. All
add certain commn features such as (a) the capability to ssh into the
add certain common features such as (a) the capability to ssh into the
Linux running on the box, (b) European WiFi channels, and (c) VPN
service.</para>
@ -459,6 +459,14 @@ Supports SNMP/mrtg. Said to have a good interface, convenient for home use.
<listitem><para>
Intended for Wireless ISPs, lots of stuff for routing and repeater operation.
Open source, but you can buy support and private-release subscriptions.
This outfit has been slammed for GPL noncompliance and apparently lost
a lot of the good reputation it used to have.
</para></listitem>
</varlistentry>
<varlistentry>
<term><ulink url='http://dd-wrt.com'>DD-WRT</ulink></term>
<listitem><para>
A fork of the SveaSoft codebase from a few years back.
</para></listitem>
</varlistentry>
<varlistentry>
@ -501,8 +509,8 @@ Wrt54g</ulink> by Seattle wireless.net.</para>
</sect1>
<sect1 id="Utilities"><title>Utilities</title>
<para>There is a Unix utility called <application>linksysmon</application> that
talks with these boxes via SNMP. There is a <ulink
<para>There is a Unix utility called <application>linksysmon</application>
that talks with these boxes via SNMP. Look at the <ulink
url="http://woogie.net/linksysmon/">Linksysmon project site</ulink>.</para>
<para>Linksysmon is a tool for monitoring Linksys BEFSR41 and BEFSR11