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 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 Version 3.8
Blaeberry release, 02/26/06 Blaeberry release, 02/26/06

View File

@ -43,7 +43,7 @@ prepend.sh (lines 18 and 28)
array-assign.bash array-assign.bash
cdll (lines 51-53, 59, 63-69, 82-83, 85, 463, 521, 567-568, 570, cdll (lines 51-53, 59, 63-69, 82-83, 85, 463, 521, 567-568, 570,
580-586, 637, 656-658) 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) is-spammer.sh (comments on lines 4, 35, and 51)
bashrc (comments on lines 596 and 618) bashrc (comments on lines 596 and 618)
commentblock.sh (lines 4 and 23) commentblock.sh (lines 4 and 23)
@ -52,7 +52,6 @@ self-document2.sh (line 8)
dev-tcp.sh (line 14) dev-tcp.sh (line 14)
archiveweblogs.sh (comment in line 4) archiveweblogs.sh (comment in line 4)
multiple-processes.sh (line 143) multiple-processes.sh (line 143)
directory-info.sh (lines 36 and 166)
catscripts.sh (lines 12 and 21) catscripts.sh (lines 12 and 21)
is_spammer.bash (comments on various lines) is_spammer.bash (comments on various lines)
iscan.sh (comment in line 10) 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; --> &) quote-fetch.sh (comment in line 26: &amp; --> &)
ftpget.sh (comment in line 28) ftpget.sh (comment in line 28)
whx.sh (comment in line 259) 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 testcgi SYSTEM "test-cgi.sh">
<!ENTITY spawnscr SYSTEM "spawn.sh"> <!ENTITY spawnscr SYSTEM "spawn.sh">
<!ENTITY iscan SYSTEM "iscan.sh"> <!ENTITY iscan SYSTEM "iscan.sh">
<!ENTITY ra2ogg SYSTEM "ra2ogg.sh">
<!ENTITY namesdata SYSTEM "names.data"> <!ENTITY namesdata SYSTEM "names.data">
<!ENTITY hashlib SYSTEM "Hash.lib"> <!ENTITY hashlib SYSTEM "Hash.lib">
<!ENTITY hashexample SYSTEM "hash-example.sh"> <!ENTITY hashexample SYSTEM "hash-example.sh">
@ -350,19 +351,12 @@ Uncomment line below to generate index.
</affiliation> </affiliation>
</author> </author>
<releaseinfo>3.8</releaseinfo> <releaseinfo>3.9</releaseinfo>
<pubdate>26 February 2006</pubdate> <pubdate>15 May 2006</pubdate>
<revhistory> <revhistory>
<revision>
<revnumber>3.6</revnumber>
<date>28 Aug 2005</date>
<authorinitials>mc</authorinitials>
<revremark>'POKEBERRY' release: Bugfix Update.</revremark>
</revision>
<revision> <revision>
<revnumber>3.7</revnumber> <revnumber>3.7</revnumber>
<date>23 Oct 2005</date> <date>23 Oct 2005</date>
@ -377,6 +371,13 @@ Uncomment line below to generate index.
<revremark>'BLAEBERRY' release: Minor Update.</revremark> <revremark>'BLAEBERRY' release: Minor Update.</revremark>
</revision> </revision>
<revision>
<revnumber>3.9</revnumber>
<date>15 May 2006</date>
<authorinitials>mc</authorinitials>
<revremark>'SPICEBERRY' release: Minor Update.</revremark>
</revision>
</revhistory> </revhistory>
@ -397,7 +398,7 @@ Uncomment line below to generate index.
introduction to programming concepts.</para> introduction to programming concepts.</para>
<para><ulink <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 The latest update of this document</ulink>, as an archived, <link
linkend="bzipref">bzip2-ed</link> <quote>tarball</quote> linkend="bzipref">bzip2-ed</link> <quote>tarball</quote>
including both the SGML source and rendered HTML, may 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 shell directives. The second example, above, requires the
initial <token>#!</token>, since the variable assignment line, initial <token>#!</token>, since the variable assignment line,
<userinput>lines=50</userinput>, uses a shell-specific construct. <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 Note again that <userinput>#!/bin/sh</userinput> invokes the default
shell interpreter, which defaults to <filename>/bin/bash</filename> shell interpreter, which defaults to <filename>/bin/bash</filename>
on a Linux machine.</para> on a Linux machine.</para>
@ -1672,7 +1678,7 @@ echo $var2 # 23skidoo</programlisting>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><token>$$</token></term> <term><anchor id="processidref"><token>$$</token></term>
<indexterm> <indexterm>
<primary>$$</primary> <primary>$$</primary>
</indexterm> </indexterm>
@ -1690,8 +1696,15 @@ echo $var2 # 23skidoo</programlisting>
<listitem><formalpara><title>process ID variable</title> <listitem><formalpara><title>process ID variable</title>
<para>The <link linkend="proccid">$$ variable</link> <para>The <link linkend="proccid">$$ variable</link>
holds the <emphasis>process ID</emphasis> of the script in holds the <emphasis>process ID</emphasis>
which it appears.</para> <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> </formalpara>
</listitem> </listitem>
@ -1790,11 +1803,12 @@ cp file22.{txt,backup}
<listitem> <listitem>
<para><anchor id="codeblockref"></para> <para><anchor id="codeblockref"></para>
<formalpara><title>Block of code [curly brackets]</title> <formalpara><title>Block of code [curly brackets]</title>
<para>Also referred to as an <quote>inline group</quote>, <para>Also referred to as an <firstterm>inline group</firstterm>,
this construct, in effect, creates an anonymous this construct, in effect, creates an <firstterm>anonymous
function. However, unlike a <link function</firstterm> (a function without a
name). However, unlike in a <quote>standard</quote> <link
linkend="functionref">function</link>, the variables 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> script.</para></formalpara>
<para> <screen><prompt>bash$ </prompt><userinput>{ local a; <para> <screen><prompt>bash$ </prompt><userinput>{ local a;
@ -1974,7 +1988,7 @@ echo ${Array[1]}</programlisting></para>
<varlistentry> <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> <indexterm>
<primary>></primary> <primary>></primary>
</indexterm> </indexterm>
@ -2026,10 +2040,17 @@ echo ${Array[1]}</programlisting></para>
to <filename>stderr</filename>.</para> to <filename>stderr</filename>.</para>
<para><userinput>scriptname >>filename</userinput> appends <para><userinput>scriptname >>filename</userinput> appends
the output of <filename>scriptname</filename> the output of <filename>scriptname</filename>
to file <filename>filename</filename>. If to file <filename>filename</filename>. If
<filename>filename</filename> does not already exist, <filename>filename</filename> does not already exist,
it will be created.</para> 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> <formalpara><title><link linkend="processsubref">process substitution</link></title>
@ -2429,11 +2450,11 @@ fi</programlisting>
# If there are hidden files in /source/directory. # If there are hidden files in /source/directory.
</programlisting></para> </programlisting></para>
<para><programlisting>bunzip2 linux-2.6.13.tar.bz2 | tar xvf - <para><programlisting>bunzip2 -c linux-2.6.16.tar.bz2 | tar xvf -
# --uncompress tar file-- | --then pass it to "tar"-- # --uncompress tar file-- | --then pass it to "tar"--
# If "tar" has not been patched to handle "bunzip2", # If "tar" has not been patched to handle "bunzip2",
# this needs to be done in two discrete steps, using a pipe. #+ this needs to be done in two discrete steps, using a pipe.
# The purpose of the exercise is to unarchive "bzipped" kernel source. # The purpose of the exercise is to unarchive "bzipped" kernel source.
</programlisting></para> </programlisting></para>
<para>Note that in this context the <quote>-</quote> is not <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 <para>The <varname>$PPID</varname> of a process is
the process ID (<varname>pid</varname>) of its parent process. the process ID (<varname>pid</varname>) of its parent process.
<footnote><para>The PID of the currently running script is <footnote>
<varname>$$</varname>, of course.</para></footnote> <para>The PID of the currently running script is
<varname>$$</varname>, of course.</para>
</footnote>
</para> </para>
<para>Compare this with the <link <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> # Strip out longest match between 'b' and 'c', from back of $stringZ.</programlisting>
</para> </para>
<para>This operator is useful for generating filenames.</para>
<example id="cvt"> <example id="cvt">
<title>Converting graphic file formats, with filename change</title> <title>Converting graphic file formats, with filename change</title>
<programlisting>&cvt;</programlisting> <programlisting>&cvt;</programlisting>
</example> </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> <para>A simple emulation of <link linkend="getopty">getopt</link>
using substring extraction constructs.</para> using substring extraction constructs.</para>
@ -8629,6 +8660,7 @@ echo $? # 1
<para>The argument <replaceable>list</replaceable> may contain wild cards.</para> <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 <para>If <firstterm>do</firstterm> is on same line as
<firstterm>for</firstterm>, there needs to be a semicolon <firstterm>for</firstterm>, there needs to be a semicolon
after list.</para> after list.</para>
@ -8816,7 +8848,7 @@ echo $? # 1
</cmdsynopsis></para> </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 placing the <firstterm>do</firstterm> on the same line as
the condition test requires a semicolon.</para> the condition test requires a semicolon.</para>
@ -12222,7 +12254,7 @@ OneYearAgo=$(date --date='1 year ago')</programlisting></para>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><command>sleep</command></term> <term><anchor id="sleepref"><command>sleep</command></term>
<indexterm> <indexterm>
<primary>sleep</primary> <primary>sleep</primary>
</indexterm> </indexterm>
@ -13886,6 +13918,11 @@ function write_utf8_string {
command is <command>gunzip</command>, which is the equivalent of command is <command>gunzip</command>, which is the equivalent of
<command>gzip -d</command>.</para> <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 <para>The <command>zcat</command> filter decompresses a
<emphasis>gzipped</emphasis> file to <emphasis>gzipped</emphasis> file to
<filename>stdout</filename>, as possible input to a pipe or <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 utility). The <command>zcat</command> command is equivalent to
<command>gzip -dc</command>.</para> <command>gzip -dc</command>.</para>
<caution><para>On some commercial UNIX systems, <command>zcat</command> <caution><para>On some commercial UNIX systems, <command>zcat</command>
is a synonym for <command>uncompress -c</command>, is a synonym for <command>uncompress -c</command>,
and will not work on <emphasis>gzipped</emphasis> and will not work on <emphasis>gzipped</emphasis>
@ -16325,6 +16363,22 @@ done</programlisting></para>
linkend="fdiskref">fdisk</link>. It may have unintended linkend="fdiskref">fdisk</link>. It may have unintended
side-effects.</para></warning> 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> </listitem>
</varlistentry> </varlistentry>
@ -17758,18 +17812,23 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ</programlisting><
</indexterm> </indexterm>
<indexterm> <indexterm>
<primary>command</primary> <primary>command</primary>
<secondary>strace</secondary> <secondary>trace</secondary>
</indexterm> </indexterm>
<listitem> <listitem>
<para>Diagnostic and debugging tool for tracing system <para><command>S</command>ystem <command>trace</command>:
calls and signals. The simplest way of invoking it is diagnostic and debugging tool for tracing <firstterm>system
<command>strace COMMAND</command>.</para> 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> <para>
<screen><prompt>bash$ </prompt><userinput>strace df</userinput> <screen><prompt>bash$ </prompt><userinput>strace df</userinput>
<computeroutput>execve("/bin/df", ["df"], [/* 45 vars */]) = 0 <computeroutput>execve("/bin/df", ["df"], [/* 45 vars */]) = 0
uname({sys="Linux", node="bozo.localdomain", ...}) = 0 uname({sys="Linux", node="bozo.localdomain", ...}) = 0
brk(0) = 0x804f5e4 brk(0) = 0x804f5e4
...</computeroutput> ...</computeroutput>
</screen> </screen>
</para> </para>
@ -17780,6 +17839,37 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ</programlisting><
</listitem> </listitem>
</varlistentry> </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> <varlistentry>
<term><anchor id="nmapref"><command>nmap</command></term> <term><anchor id="nmapref"><command>nmap</command></term>
<indexterm> <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> <title><anchor id="jobcontrolsys1">Job Control</title>
<varlistentry> <varlistentry>
<term><command>ps</command></term> <term><anchor id="ppssref"><command>ps</command></term>
<indexterm> <indexterm>
<primary>ps</primary> <primary>ps</primary>
</indexterm> </indexterm>
@ -19364,6 +19454,7 @@ mount -o loop /dev/loop0 /mnt # Mount it.
bMaxPacketSize0 8 bMaxPacketSize0 8
idVendor 0x0000 idVendor 0x0000
idProduct 0x0000 idProduct 0x0000
. . .</computeroutput> . . .</computeroutput>
</screen> </screen>
</para> </para>
@ -19371,6 +19462,36 @@ mount -o loop /dev/loop0 /mnt # Mount it.
</listitem> </listitem>
</varlistentry> </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> <varlistentry>
<term><command>mkbootdisk</command></term> <term><command>mkbootdisk</command></term>
<indexterm> <indexterm>
@ -20588,17 +20709,26 @@ let "z += 3" # Quotes permit the use of spaces in variable assignment.
# -------------------------------------------------------------------- # --------------------------------------------------------------------
1>filename 1>filename
# Redirect stdout to file "filename". # Redirect stdout to file "filename."
1>>filename 1>>filename
# Redirect and append stdout to file "filename". # Redirect and append stdout to file "filename."
2>filename 2>filename
# Redirect stderr to file "filename". # Redirect stderr to file "filename."
2>>filename 2>>filename
# Redirect and append stderr to file "filename". # Redirect and append stderr to file "filename."
&>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. # Redirecting stdout, one line at a time.
LOGFILE=script.log 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 file. This sends all command output that would normally go
to <filename>stdout</filename> to that file.</para> 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"> <example id="reassignstdout">
<title>Redirecting <filename>stdout</filename> using <title>Redirecting <filename>stdout</filename> using
<command>exec</command></title> <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><anchor id="herestringsref"></para>
<para>A <emphasis>here string</emphasis> can be considered as <para>A <firstterm>here string</firstterm> can be considered as
a stripped-down form of <emphasis>here document</emphasis>. It a stripped-down form of a <firstterm>here document</firstterm>.
consists of nothing more than <command>COMMAND It consists of nothing more than <command>COMMAND
&lt;&lt;&lt;$WORD</command>, where <varname>$WORD</varname> &lt;&lt;&lt;$WORD</command>, where <varname>$WORD</varname>
is expanded and fed to the <filename>stdin</filename> of is expanded and fed to the <filename>stdin</filename> of
<varname>COMMAND</varname>.</para> <varname>COMMAND</varname>.</para>
@ -21455,6 +21601,8 @@ exit 0</programlisting></para></footnote>
<para><anchor id="dollarsignref"></para> <para><anchor id="dollarsignref"></para>
<para>The dollar sign -- <token>$</token> -- at the end of an <para>The dollar sign -- <token>$</token> -- at the end of an
RE matches the end of a line.</para> 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> <para><quote>^$</quote> matches blank lines.</para>
</listitem> </listitem>
@ -22246,7 +22394,7 @@ fi
<note><para>A command block between <replaceable>curly <note><para>A command block between <replaceable>curly
braces</replaceable> does <emphasis>not</emphasis> launch braces</replaceable> does <emphasis>not</emphasis> launch
a subshell.</para> a subshell.</para>
<para>{ command1; command2; command3; ... }</para></note> <para>{ command1; command2; command3; . . . commandN; }</para></note>
</chapter> <!-- Subshells --> </chapter> <!-- Subshells -->
@ -24574,7 +24722,14 @@ trap 'echo "Control-C disabled."' 2
<para><anchor id="bash3gotcha"></para> <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. <programlisting>case=value0 # Causes problems.
23skidoo=value1 # Also problems. 23skidoo=value1 # Also problems.
# Variable names starting with a digit are reserved by the shell. # 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. xyz((!*=value2 # Causes severe problems.
# As of version 3 of Bash, periods are not allowed within variable names.</programlisting> # As of version 3 of Bash, periods are not allowed within variable names.</programlisting>
</para> </para>
</listitem>
<listitem>
<para>Using a hyphen or other reserved characters in a variable name (or <para>Using a hyphen or other reserved characters in a variable name (or
function name). function name).</para>
<para>
<programlisting>var-1=23 <programlisting>var-1=23
# Use 'var_1' instead. # Use 'var_1' instead.
@ -24601,9 +24759,12 @@ function-whatever () # Error
function.whatever () # Error function.whatever () # Error
# Use 'functionWhatever ()' instead.</programlisting> # Use 'functionWhatever ()' instead.</programlisting>
</para> </para>
</listitem>
<listitem>
<para>Using the same name for a variable and a function. This can make a <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 () <programlisting>do_something ()
{ {
echo "This function does something with \"$1\"." echo "This function does something with \"$1\"."
@ -24615,13 +24776,17 @@ do_something do_something
# All this is legal, but highly confusing.</programlisting> # All this is legal, but highly confusing.</programlisting>
</para> </para>
</listitem>
<listitem>
<para><anchor id="wsbad">Using <link <para><anchor id="wsbad">Using <link
linkend="whitespaceref">whitespace</link> inappropriately. linkend="whitespaceref">whitespace</link> inappropriately.
In contrast to other programming languages, Bash can be quite 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. <programlisting>var1 = 23 # 'var1=23' is correct.
# On line above, Bash attempts to execute command "var1" # On line above, Bash attempts to execute command "var1"
# with the arguments "=" and "23". # 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. # if [ "$a" -le 5 ] is even better.
# [[ $a -le 5 ]] also works.</programlisting> # [[ $a -le 5 ]] also works.</programlisting>
</para> </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> <para>
Assuming uninitialized variables (variables before a value is Assuming uninitialized variables (variables before a value is
assigned to them) are <quote>zeroed out</quote>. An assigned to them) are <quote>zeroed out</quote>. An
uninitialized variable has a value of <quote>null</quote>, uninitialized variable has a value of <quote>null</quote>,
<emphasis>not</emphasis> zero. <emphasis>not</emphasis> zero.</para>
<para>
<programlisting>#!/bin/bash <programlisting>#!/bin/bash
echo "uninitialized_var = $uninitialized_var" echo "uninitialized_var = $uninitialized_var"
# uninitialized_var =</programlisting> # uninitialized_var =</programlisting>
</para> </para>
</listitem>
<listitem>
<para>Mixing up <emphasis>=</emphasis> and <emphasis>-eq</emphasis> in <para>Mixing up <emphasis>=</emphasis> and <emphasis>-eq</emphasis> in
a test. Remember, <emphasis>=</emphasis> is for comparing literal 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? <programlisting>if [ "$a" = 273 ] # Is $a an integer or string?
if [ "$a" -eq 273 ] # If $a is an integer. if [ "$a" -eq 273 ] # If $a is an integer.
@ -24677,8 +24864,10 @@ then
fi # Aborts with an error message. fi # Aborts with an error message.
# test.sh: [: 273.0: integer expression expected</programlisting> # test.sh: [: 273.0: integer expression expected</programlisting>
</para> </para>
</listitem>
<listitem>
<para>Misusing <link linkend="scomparison1">string comparison</link> <para>Misusing <link linkend="scomparison1">string comparison</link>
operators.</para> operators.</para>
@ -24686,41 +24875,55 @@ fi # Aborts with an error message.
<title>Numerical and string comparison are not equivalent</title> <title>Numerical and string comparison are not equivalent</title>
<programlisting>&badop;</programlisting> <programlisting>&badop;</programlisting>
</example> </example>
</listitem>
<listitem>
<para>Sometimes variables within <quote>test</quote> brackets <para>Sometimes variables within <quote>test</quote> brackets
([ ]) need to be quoted (double quotes). Failure to do so may ([ ]) need to be quoted (double quotes). Failure to do so may
cause unexpected behavior. See <xref linkend="strtest">, <xref cause unexpected behavior. See <xref linkend="strtest">, <xref
linkend="redir2">, and <xref linkend="arglist">.</para> linkend="redir2">, and <xref linkend="arglist">.</para>
</listitem>
<listitem>
<para>Commands issued from a script may fail to execute because <para>Commands issued from a script may fail to execute because
the script owner lacks execute permission for them. If a user the script owner lacks execute permission for them. If a user
cannot invoke a command from the command line, then putting it cannot invoke a command from the command line, then putting it
into a script will likewise fail. Try changing the attributes of into a script will likewise fail. Try changing the attributes of
the command in question, perhaps even setting the suid bit the command in question, perhaps even setting the suid bit
(as root, of course).</para> (as root, of course).</para>
</listitem>
<listitem>
<para>Attempting to use <command>-</command> as a redirection <para>Attempting to use <command>-</command> as a redirection
operator (which it is not) will usually result in an unpleasant 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... <programlisting>command1 2&gt; - | command2 # Trying to redirect error output of command1 into a pipe...
# ...will not work. # ...will not work.
command1 2&gt;&amp; - | command2 # Also futile. command1 2&gt;&amp; - | command2 # Also futile.
Thanks, S.C.</programlisting></para> Thanks, S.C.</programlisting></para>
</listitem>
<listitem>
<para>Using Bash <link linkend="bash2ref">version 2+</link> <para>Using Bash <link linkend="bash2ref">version 2+</link>
functionality may cause a bailout with error messages. Older functionality may cause a bailout with error messages. Older
Linux machines may have version 1.XX of Bash as the default Linux machines may have version 1.XX of Bash as the default
installation. installation.</para>
<para>
<programlisting>#!/bin/bash <programlisting>#!/bin/bash
minimum_version=2 minimum_version=2
# Since Chet Ramey is constantly adding features to Bash, # 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 E_BAD_VERSION=80
if [ "$BASH_VERSION" \< "$minimum_version" ] if [ "$BASH_VERSION" \< "$minimum_version" ]
@ -24731,14 +24934,19 @@ then
fi fi
...</programlisting></para> ...</programlisting></para>
</listitem>
<listitem>
<para>Using Bash-specific functionality in a Bourne shell script <para>Using Bash-specific functionality in a Bourne shell script
(<userinput>#!/bin/sh</userinput>) on a non-Linux machine (<userinput>#!/bin/sh</userinput>) on a non-Linux machine
may cause unexpected behavior. A Linux system usually aliases may cause unexpected behavior. A Linux system usually aliases
<command>sh</command> to <command>bash</command>, but this does <command>sh</command> to <command>bash</command>, but this does
not necessarily hold true for a generic UNIX machine.</para> not necessarily hold true for a generic UNIX machine.</para>
</listitem>
<listitem>
<para>Using undocumented features in Bash turns out to be a <para>Using undocumented features in Bash turns out to be a
dangerous practice. In previous releases of this dangerous practice. In previous releases of this
book there were several scripts that depended on the book there were several scripts that depended on the
@ -24748,13 +24956,18 @@ fi
did not apply to <emphasis>negative</emphasis> integers. did not apply to <emphasis>negative</emphasis> integers.
Unfortunately, in version 2.05b and later, that loophole Unfortunately, in version 2.05b and later, that loophole
disappeared. See <xref linkend="returntest">.</para> disappeared. See <xref linkend="returntest">.</para>
</listitem>
<listitem>
<para> <para>
A script with DOS-type newlines (<replaceable>\r\n</replaceable>) A script with DOS-type newlines (<replaceable>\r\n</replaceable>)
will fail to execute, since <userinput>#!/bin/bash\r\n</userinput> will fail to execute, since <userinput>#!/bin/bash\r\n</userinput>
is not recognized, <emphasis>not</emphasis> the same as the is <emphasis>not</emphasis> recognized, <emphasis>not</emphasis>
expected <userinput>#!/bin/bash\n</userinput>. The fix is to the same as the expected <userinput>#!/bin/bash\n</userinput>. The
convert the script to UNIX-style newlines. fix is to convert the script to UNIX-style newlines.</para>
<para>
<programlisting>#!/bin/bash <programlisting>#!/bin/bash
echo "Here" echo "Here"
@ -24771,24 +24984,34 @@ echo "There"
exit 0</programlisting> exit 0</programlisting>
</para> </para>
</listitem>
<listitem>
<para>A shell script headed by <userinput>#!/bin/sh</userinput> <para>A shell script headed by <userinput>#!/bin/sh</userinput>
will not run in full Bash-compatibility mode. Some Bash-specific will not run in full Bash-compatibility mode. Some Bash-specific
functions might be disabled. Scripts that need complete functions might be disabled. Scripts that need complete
access to all the Bash-specific extensions should start with access to all the Bash-specific extensions should start with
<userinput>#!/bin/bash</userinput>.</para> <userinput>#!/bin/bash</userinput>.</para>
</listitem>
<listitem>
<para><link linkend="indentedls">Putting whitespace in front of <para><link linkend="indentedls">Putting whitespace in front of
the terminating limit string</link> of a <link the terminating limit string</link> of a <link
linkend="heredocref">here document</link> will cause unexpected linkend="heredocref">here document</link> will cause unexpected
behavior in a script.</para> behavior in a script.</para>
</listitem>
<listitem>
<para><anchor id="parchildprobref"></para> <para><anchor id="parchildprobref"></para>
<para>A script may not <command>export</command> variables back <para>A script may not <command>export</command> variables back
to its <link linkend="forkref">parent process</link>, the shell, to its <link linkend="forkref">parent process</link>, the shell,
or to the environment. Just as we learned in biology, a child 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 <programlisting>WHATEVER=/home/bozo
export WHATEVER export WHATEVER
exit 0</programlisting> exit 0</programlisting>
@ -24797,9 +25020,16 @@ exit 0</programlisting>
</computeroutput> </computeroutput>
<prompt>bash$ </prompt></screen> <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 <para>Setting and manipulating variables in a <link
linkend="subshellsref">subshell</link>, then attempting linkend="subshellsref">subshell</link>, then attempting
to use those same variables outside the scope of the subshell will to use those same variables outside the scope of the subshell will
@ -24809,7 +25039,11 @@ exit 0</programlisting>
<title>Subshell Pitfalls</title> <title>Subshell Pitfalls</title>
<programlisting>&subpit;</programlisting> <programlisting>&subpit;</programlisting>
</example> </example>
</listitem>
<listitem>
<para><anchor id="badread0"></para> <para><anchor id="badread0"></para>
<para><link linkend="piperef">Piping</link> <para><link linkend="piperef">Piping</link>
<command>echo</command> output to a <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 <programlisting>tail -f /var/log/messages | grep "$ERROR_MSG" >> error.log
# The "error.log" file will not have anything written to it.</programlisting> # The "error.log" file will not have anything written to it.</programlisting>
</para> </para>
</listitem>
<para>--</para>
<listitem>
<para>Using <quote>suid</quote> commands within scripts is risky, <para>Using <quote>suid</quote> commands within scripts is risky,
as it may compromise system security. as it may compromise system security.
<footnote><para>Setting the <emphasis>suid</emphasis> permission on <footnote><para>Setting the <emphasis>suid</emphasis> permission on
the script itself has no effect.</para></footnote> the script itself has no effect.</para></footnote>
</para> </para>
</listitem>
<listitem>
<para>Using shell scripts for CGI programming may be problematic. Shell <para>Using shell scripts for CGI programming may be problematic. Shell
script variables are not <quote>typesafe</quote>, and this can cause script variables are not <quote>typesafe</quote>, and this can cause
undesirable behavior as far as CGI is concerned. Moreover, it is undesirable behavior as far as CGI is concerned. Moreover, it is
difficult to <quote>cracker-proof</quote> shell scripts.</para> difficult to <quote>cracker-proof</quote> shell scripts.</para>
</listitem>
<listitem>
<para>Bash does not handle the <link linkend="doubleslashref">double slash <para>Bash does not handle the <link linkend="doubleslashref">double slash
(<token>//</token>) string</link> correctly.</para> (<token>//</token>) string</link> correctly.</para>
</listitem>
<listitem>
<para>Bash scripts written for Linux or BSD systems may need <para>Bash scripts written for Linux or BSD systems may need
fixups to run on a commercial UNIX (or Apple OSX) machine. Such fixups to run on a commercial UNIX (or Apple OSX) machine. Such
scripts often employ GNU commands and filters which have greater scripts often employ GNU commands and filters which have greater
functionality than their generic UNIX counterparts. This is functionality than their generic UNIX counterparts. This is
particularly true of such text processing utilites as <link particularly true of such text processing utilites as <link
linkend="trref">tr</link>.</para> linkend="trref">tr</link>.</para>
</listitem>
</itemizedlist>
<epigraph> <epigraph>
<attribution>A.J. Lamb and H.W. Petrie</attribution> <attribution>A.J. Lamb and H.W. Petrie</attribution>
@ -26563,6 +26809,51 @@ fi</programlisting></para>
</caution> </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 --> </sect1> <!-- Bash, Version 3 -->
</chapter> <!-- Bash, versions 2 and 3 --> </chapter> <!-- Bash, versions 2 and 3 -->
@ -26861,7 +27152,8 @@ fi</programlisting></para>
Chris Morgan, Walter Dnes, Linc Fessenden, Michael Iatrou, Pharis Chris Morgan, Walter Dnes, Linc Fessenden, Michael Iatrou, Pharis
Monalo, Jesse Gough, Fabian Kreutz, Mark Norman, Harald Koenig, Monalo, Jesse Gough, Fabian Kreutz, Mark Norman, Harald Koenig,
Peter Knowles, Francisco Lobo, Mariusz Gniazdowski, Tedman Eng, 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 <para>My gratitude to <ulink url="mailto:chet@po.cwru.edu">Chet
Ramey</ulink> and Brian Fox for writing <firstterm>Bash</firstterm>, 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> <entry><link linkend="ivrref">Indirect variable reference</link></entry>
</row> </row>
<row> <row>
<entry><option>{ command1; command2 }</option></entry> <entry><option>{ command1; command2; . . . commandN; }</option></entry>
<entry>Block of code</entry> <entry>Block of code</entry>
</row> </row>
<row> <row>
@ -30629,6 +30921,18 @@ done < `tail -f /var/log/messages`</programlisting>
</listitem> </listitem>
</varlistentry> </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> <varlistentry>
<term><command>Primes</command></term> <term><command>Primes</command></term>
<listitem> <listitem>
@ -31351,7 +31655,7 @@ fairly detailed rundown on the Playfair Cipher and its solution methods.</progra
<title>Revision History</title> <title>Revision History</title>
<synopsis> <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 of 2000. Since then, it has gone through quite a number of
updates and revisions. This book could not have been written updates and revisions. This book could not have been written
without the assistance of the Linux community, and especially 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> <row>
<entry><option>3.5</option></entry> <entry><option>3.5</option></entry>
<entry>05 Jun 2005</entry> <entry>05 Jun 2005</entry>
<entry>BOXBERRY release: Bugfixes, some materials added.</entry> <entry>BOXBERRY release: Bugfixes, some material added.</entry>
</row> </row>
<row> <row>
<entry><option>3.6</option></entry> <entry><option>3.6</option></entry>
<entry>28 Aug 2005</entry> <entry>28 Aug 2005</entry>
<entry>POKEBERRY release: Bugfixes, some materials added.</entry> <entry>POKEBERRY release: Bugfixes, some material added.</entry>
</row> </row>
<row> <row>
<entry><option>3.7</option></entry> <entry><option>3.7</option></entry>
<entry>23 Oct 2005</entry> <entry>23 Oct 2005</entry>
<entry>WHORTLEBERRY release: Bugfixes, some materials added.</entry> <entry>WHORTLEBERRY release: Bugfixes, some material added.</entry>
</row> </row>
<row> <row>
<entry><option>3.8</option></entry> <entry><option>3.8</option></entry>
<entry>26 Feb 2006</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> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@ -31555,7 +31864,7 @@ fairly detailed rundown on the Playfair Cipher and its solution methods.</progra
<title>Mirror Sites</title> <title>Mirror Sites</title>
<para><ulink <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 The latest update of this document</ulink>, as an archived
<quote>tarball</quote> <quote>tarball</quote>
including both the SGML source and rendered HTML, may including both the SGML source and rendered HTML, may

View File

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

View File

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

View File

@ -13,7 +13,7 @@
#+ The gcd = dividend, on the final pass. #+ The gcd = dividend, on the final pass.
# #
# For an excellent discussion of Euclid's algorithm, see # 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. 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? # Why not?
remainder=1 # If uninitialized variable used in loop, 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. if [ -n "$1" ] # Specify another "generation 0" file.
then then
if [ -e "$1" ] # Check for existence.
then
startfile="$1" startfile="$1"
fi
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=. ALIVE1=.
DEAD1=_ DEAD1=_
@ -337,9 +348,9 @@ done
echo echo
exit 0 exit 0 # END
# --------------------------------------------------------------
# The grid in this script has a "boundary problem." # The grid in this script has a "boundary problem."
# The the top, bottom, and sides border on a void of dead cells. # 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: # 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 # 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. #+ p. 137, ff.

View File

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

View File

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

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://docbook.org/xml/4.2/docbookx.dtd" [ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY howto "http://www.tldp.org/HOWTO/"> <!ENTITY howto "http://www.tldp.org/HOWTO/">
<!ENTITY mini-howto "http://www.tldp.org/HOWTO/mini/"> <!ENTITY mini-howto "http://www.tldp.org/HOWTO/mini/">
<!ENTITY home "http://www.catb.org/~esr/"> <!ENTITY home "http://www.catb.org/~esr/">
@ -20,6 +20,15 @@
</author> </author>
<revhistory> <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> <revision>
<revnumber>2.2</revnumber> <revnumber>2.2</revnumber>
<date>2005-12-01</date> <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 <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 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> VxWorks OS.</para>
</sect2> </sect2>
@ -184,9 +193,7 @@ ignore you.</para>
to be used as gateway boxes on a home Ethernet. Typically, you'll hook one 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 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. mode and simply pass packets between your ISP's router and the Linksys box.
Here's a <ulink </para>
url='http://www.linksys.com/products/group.asp?grid=33&amp;scid=35'>recognition
chart</ulink> of these products.</para>
<para>If you want to use a general-purpose PC running Linux as a firewall, <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 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 Unfortunately when I tried other low-end brands (Belkin, Buffalo) they
proved to have gross design errors. The Belkin had brain-damage in its proved to have gross design errors. The Belkin had brain-damage in its
firewall rules that interfered with local SMTP, and the Buffalo firewall rules that interfered with local SMTP, and the Buffalo
intermittently refused connections for no apparent reason. So I'm back intermittently refused connections for no apparent reason. So I went back
with Linksys. hoping my WRT54G doesn't turn into a doorstop within a couple with Linksys, hoping my WRT54G wouldn't turn into a doorstop within a couple
of months.</para> 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 <para>(Building one of these puppies is not rocket science. I can only
conjecture that the competitive pressure is driving the manufacturers to cut 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. margins and brand image of Cisco's commercial-grade networking products.
This means that Linksys boxes are no longer acquiring new firmware This means that Linksys boxes are no longer acquiring new firmware
features, and some old ones like stateful packet inspection almost features, and some old ones like stateful packet inspection almost
certainly won't be coming back. Provided you can live wthin these limits, certainly won't be coming back. Provided you can live within these limits,
this is actually good; simpler firmware is stable firmware.</para> this is actually good; simpler firmware is more stable firmware.</para>
<para>At minimum, a live Linksys box will do the following things for <para>At minimum, a live Linksys box will do the following things for
you:</para> you:</para>
@ -260,7 +267,7 @@ built into the firmware, a good thing if your net connection is
down.</para> down.</para>
<para>Unfortunately, you're in trouble if you have to bring in Linksys tech <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 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 at it. Both were complete and utter idiots whose response to any
nontrivial question was to put me on infinite hold while they went 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 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 means that if you leave your password at default, any script kiddie can
break in, steal your WEP, and scramble your configuration. The Linksys break in, steal your WEP, and scramble your configuration. The Linksys
people get the moron medal with oak-leaf cluster for this people get the moron medal with oak-leaf cluster for this screwup.</para>
screwup.</para>
<para>(I don't know if this bug is still present in the 3.x firmware. It <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> would be a good idea to check.)</para>
@ -321,7 +327,7 @@ network.</para></step>
</procedure> </procedure>
<para>There are two more steps for older firmware versions only. You can <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> <procedure>
<step><para><emphasis role='bold'>Disable AOL Parental Controls.</emphasis> <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 <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 I did it the first time, before Linksys added the <quote>Upgrade
firmware</quote> to the firmware, and I document it here for completeness 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 even though I now recommend their upgrade method. There is a tftp client
with Red Hat Linux. To upgrade your firmware this way, do the following included with Red Hat Linux. To upgrade your firmware this way, do the
steps:</para> following steps:</para>
<procedure> <procedure>
<step> <step>
@ -378,9 +384,7 @@ your basic settings but clear some advanced ones.</para>
</step> </step>
<step> <step>
<para><emphasis role='bold'>Download a copy of the new firmware.</emphasis> <para><emphasis role='bold'>Download a copy of the new firmware.</emphasis>
You should find it at <ulink Follow the Downloads link from the Linkys main page. Note that
url="http://www.linksys.com/download/firmware.asp?dlid=1"> Firmware
Upgrades for your Linksys Products</ulink> on the Linksys site. Note that
what you get may well be marked <quote>For Windows Users</quote> and be a 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 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 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> Apply.</para>
</step> </step>
<step> <step>
<para><emphasis role='bold'>Cross your fingers and load the firmware.</emphasis> <para><emphasis role='bold'>Cross your fingers and load the
The command session you want will to see will look something like firmware.</emphasis> The command session you want will to see will look
this, with your router's IP address substituted for something like this, with your router's IP address substituted for
192.168.1.1:</para> 192.168.1.1:</para>
<screen> <screen>
@ -425,11 +429,7 @@ the firmware version number will have changed.</para>
</sect1> </sect1>
<sect1><title>Hacking the hardware</title> <sect1><title>Hacking the hardware</title>
<para>There is a <ulink <para>Linksys boxes have firmware support for a serial console. The circuit
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
board has traces for two serial ports, but you have to do some fairly board has traces for two serial ports, but you have to do some fairly
serious modding to get them working. <ulink serious modding to get them working. <ulink
url="http://www.rwhitby.net/wrt54gs/serial.html">This page</ulink> will url="http://www.rwhitby.net/wrt54gs/serial.html">This page</ulink> will
@ -438,12 +438,12 @@ show you how.</para>
</sect1> </sect1>
<sect1><title>Hacking the software</title> <sect1><title>Hacking the software</title>
<para>Linxsys routers run Linux from firmware. Linksys supplies <ulink <para>Linksys routers run Linux from firmware. Linksys supplies source
url="http://www.linksys.com/support/gpl.asp">source code</ulink> on its code on its site; look for "GPL Code Center" under technical
site.</para> support.</para>
<para>There are several replacements for the WRT54G firmware. All <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 Linux running on the box, (b) European WiFi channels, and (c) VPN
service.</para> service.</para>
@ -459,6 +459,14 @@ Supports SNMP/mrtg. Said to have a good interface, convenient for home use.
<listitem><para> <listitem><para>
Intended for Wireless ISPs, lots of stuff for routing and repeater operation. Intended for Wireless ISPs, lots of stuff for routing and repeater operation.
Open source, but you can buy support and private-release subscriptions. 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> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -501,8 +509,8 @@ Wrt54g</ulink> by Seattle wireless.net.</para>
</sect1> </sect1>
<sect1 id="Utilities"><title>Utilities</title> <sect1 id="Utilities"><title>Utilities</title>
<para>There is a Unix utility called <application>linksysmon</application> that <para>There is a Unix utility called <application>linksysmon</application>
talks with these boxes via SNMP. There is a <ulink that talks with these boxes via SNMP. Look at the <ulink
url="http://woogie.net/linksysmon/">Linksysmon project site</ulink>.</para> url="http://woogie.net/linksysmon/">Linksysmon project site</ulink>.</para>
<para>Linksysmon is a tool for monitoring Linksys BEFSR41 and BEFSR11 <para>Linksysmon is a tool for monitoring Linksys BEFSR41 and BEFSR11