mirror of https://github.com/tLDP/LDP
updated
This commit is contained in:
parent
54b9f39293
commit
dc5f74fc57
|
@ -3,18 +3,80 @@
|
|||
Release History
|
||||
|
||||
The latest version of this file is available on-line at
|
||||
http://personal.riverusers.com/~thegrendel/Change.log
|
||||
http://http://bash.neuralshortcircuit.com/Change.log
|
||||
|
||||
|
||||
==================================================================
|
||||
Current version = 5.5
|
||||
Dated 11/23/08
|
||||
http://personal.riverusers.com/~thegrendel/abs-guide-5.5.tar.bz2
|
||||
http://personal.riverusers.com/~thegrendel/abs-guide.pdf
|
||||
Current version = 5.6
|
||||
Dated 01/26/09
|
||||
|
||||
http://bash.neuralshortcircuit.com/abs-guide-latest.tar.bz2
|
||||
http://bash.neuralshortcircuit.com/abs-guide.pdf
|
||||
--------------------------------------------------------------------
|
||||
News: Mostly a bugfix release. A fair amount of new material added.
|
||||
News: Added Knight's Tour script (ktour.sh),
|
||||
Magic Square script (msquare.sh).
|
||||
--------------------------------------------------------------------
|
||||
Remarks: Gradually adding in-line definitions for technical terms,
|
||||
usually as sidebars, less often as footnotes.
|
||||
====================================================================
|
||||
|
||||
Version 5.6, Worcesterberry release
|
||||
01/26/09
|
||||
|
||||
1) In "Special Characters" chapter:
|
||||
At "#" (comments) entry, added example of comment embedded within a pipe.
|
||||
At "semicolon" entry, slightly revised comments.
|
||||
Corrected a typo in "filter" footnote ("rougly").
|
||||
At "$IFS" entry, added sidebar defining the term "field."
|
||||
|
||||
2) In "Variables Revisited" chapter:
|
||||
In "Manipulating Strings" section:
|
||||
* Expanded first inline
|
||||
"Substring Replacement example, thanks to the suggestion from
|
||||
Zhiyi Liu. Also added explanatory footnote.
|
||||
* Fixed minor typo in "rand-string.sh" example script.
|
||||
(Thank you, Ethan Larson, for bringing it to my attention.)
|
||||
|
||||
3) In "Internal Commands and Builtins" chapter:
|
||||
At "let" reference, inserted footnote that the command cannot be used
|
||||
for setting string variables.
|
||||
|
||||
4) In "Regular Expressions" chapter:
|
||||
Added example snippet of use of POSIX character classes
|
||||
(excerpted from ktour.sh example).
|
||||
|
||||
5) In "Gotchas" chapter:
|
||||
Added entry about misuse of "let" command to set string variables.
|
||||
|
||||
6) In "Contributed Scripts" appendix:
|
||||
Added "ktour.sh" -- Knight's Tour -- example script.
|
||||
Added "msquare.sh" -- Magic Square -- example script.
|
||||
|
||||
7) In "Bibliography" section:
|
||||
Added http://bashcookbook.com entry.
|
||||
Word usage cleanups in a couple of entries.
|
||||
|
||||
8) Moved the download and mirror site URLs from the title page
|
||||
to the "Download and Mirror Sites" appendix (where they rightfully
|
||||
belong!).
|
||||
Removed http://personal.riverusers/~thegrendel/ URL.
|
||||
|
||||
In Download and Mirror Sites" appendix:
|
||||
Gave Ronny Bangsund credit for graciously donating server space for
|
||||
a mirror site.
|
||||
Removed stale www.morethan.org URL.
|
||||
|
||||
Updated document author's e-mal.
|
||||
|
||||
9) Updated sample "bashrc" file (Appendix K).
|
||||
|
||||
10) Cleanups/fixups to main text, appendices, and script examples where
|
||||
appropriate.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Version 5.5, Farkleberry release
|
||||
11/28/08
|
||||
|
||||
|
@ -28,7 +90,7 @@ Version 5.5, Farkleberry release
|
|||
In "Quoting Variables" subsection, simplified introductory
|
||||
paragraph to eliminate confusion.
|
||||
|
||||
4 ) In "Special Characters" chapter:
|
||||
4) In "Special Characters" chapter:
|
||||
At "comma operator" entry, added discussion and usage example
|
||||
for string concatenation.
|
||||
(Thank you, Rory Winston!)
|
||||
|
|
|
@ -1378,6 +1378,9 @@
|
|||
returns <firstterm>unsuccessful</firstterm> (1) <link
|
||||
linkend="exitstatusref">exit status</link></para>
|
||||
|
||||
<para><link linkend="fieldref">Field</link>, a group of characters
|
||||
that comprises an item of data</para>
|
||||
|
||||
<para><link linkend="filearchiv">Files / Archiving</link></para>
|
||||
|
||||
<para><link linkend="fdref">File descriptors</link></para>
|
||||
|
@ -1495,8 +1498,12 @@
|
|||
linkend="cards">Dealing a deck of cards</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="horserace">Horse race</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="ktour">Knight's Tour</link></para></listitem>
|
||||
<listitem><para><link linkend="lifeslow"><quote>Life</quote>
|
||||
game</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="msquare">Magic Squares</link></para></listitem>
|
||||
<listitem><para><link linkend="musicscr">Music-playing
|
||||
script</link></para></listitem>
|
||||
<listitem><para><link linkend="nim">Nim</link></para></listitem>
|
||||
|
@ -2071,6 +2078,9 @@
|
|||
<listitem><para><link linkend="catabuse">Avoiding
|
||||
unnecessary commands</link> in a
|
||||
<firstterm>pipe</firstterm></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="comminpipe"><firstterm>Comments</firstterm> embedded
|
||||
within</link></para></listitem>
|
||||
<listitem><para><link linkend="pipefailref">Pipefail</link>,
|
||||
<firstterm>set -o pipefail</firstterm>
|
||||
option to indicate <link linkend="exitstatusref">exit status</link>
|
||||
|
@ -2126,6 +2136,9 @@
|
|||
within <firstterm>test</firstterm> brackets</para></listitem>
|
||||
<listitem><para><link linkend="gnuref"><firstterm>GNU</firstterm>
|
||||
command set</link>, in cross-platform scripts</para></listitem>
|
||||
<listitem><para><firstterm>let</firstterm> misuse:
|
||||
<link linkend="letbad">attempting to set string variables</link>
|
||||
</para></listitem>
|
||||
<listitem><para><link linkend="rvtcaution2">Multiple echo
|
||||
statements</link> in a <link linkend="rvt">function whose
|
||||
output is captured</link></para></listitem>
|
||||
|
|
|
@ -54,7 +54,7 @@ cdll (lines 51-53, 59, 63-69, 82-83, 85, 463, 521, 567-568, 570,
|
|||
580-586, 637, 656-658)
|
||||
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)
|
||||
bashrc (comment on line 4)
|
||||
commentblock.sh (lines 4 and 23)
|
||||
self-document.sh (line 14)
|
||||
self-document2.sh (line 8)
|
||||
|
@ -103,8 +103,8 @@ qky.sh
|
|||
line 63
|
||||
line 87
|
||||
line 113
|
||||
(The unaltered, executable script can be downloaded. See:
|
||||
http://personal.riverusers.com/~thegrendel/qky.README.html)
|
||||
(The unaltered, executable script can be downloaded.
|
||||
See: http://bash.neuralshortcircuit.com/qky.README.html)
|
||||
|
||||
maned.sh
|
||||
line 6 (comment)
|
||||
|
|
|
@ -358,6 +358,8 @@
|
|||
<!ENTITY petals SYSTEM "petals.sh">
|
||||
<!ENTITY qky SYSTEM "qky.sh">
|
||||
<!ENTITY maned SYSTEM "maned.sh">
|
||||
<!ENTITY ktour SYSTEM "ktour.sh">
|
||||
<!ENTITY msquare SYSTEM "msquare.sh">
|
||||
<!ENTITY nim SYSTEM "nim.sh">
|
||||
<!ENTITY stddev SYSTEM "sd.sh">
|
||||
<!ENTITY gen0data SYSTEM "gen0">
|
||||
|
@ -377,26 +379,19 @@
|
|||
<surname>Cooper</surname>
|
||||
<affiliation>
|
||||
<orgname></orgname>
|
||||
<address><email>thegrendel@theriver.com</email></address>
|
||||
<address><email>thegrendel.abs@gmail.com</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
|
||||
|
||||
<releaseinfo>5.5</releaseinfo>
|
||||
<pubdate>23 November 2008</pubdate>
|
||||
<releaseinfo>5.6</releaseinfo>
|
||||
<pubdate>26 January 2009</pubdate>
|
||||
<isbn>978-1-4357-5219-1</isbn>
|
||||
|
||||
|
||||
|
||||
<revhistory>
|
||||
|
||||
<revision>
|
||||
<revnumber>5.3</revnumber>
|
||||
<date>05 May 2008</date>
|
||||
<authorinitials>mc</authorinitials>
|
||||
<revremark>'GOLDENBERRY' release: Minor Update.</revremark>
|
||||
</revision>
|
||||
|
||||
<revision>
|
||||
<revnumber>5.4</revnumber>
|
||||
<date>21 July 2008</date>
|
||||
|
@ -411,6 +406,13 @@
|
|||
<revremark>'FARKLEBERRY' release: Minor Update.</revremark>
|
||||
</revision>
|
||||
|
||||
<revision>
|
||||
<revnumber>5.6</revnumber>
|
||||
<date>26 Jan 2009</date>
|
||||
<authorinitials>mc</authorinitials>
|
||||
<revremark>'WORCESTERBERRY' release: Minor Update.</revremark>
|
||||
</revision>
|
||||
|
||||
</revhistory>
|
||||
|
||||
|
||||
|
@ -430,22 +432,6 @@
|
|||
<para>This book is suitable for classroom use as a general
|
||||
introduction to programming concepts.</para>
|
||||
|
||||
|
||||
<para><anchor id="where_tarball"></para>
|
||||
|
||||
<para><ulink
|
||||
url="http://personal.riverusers.com/~thegrendel/abs-guide-5.5.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
|
||||
be downloaded from the author's home site. A <ulink
|
||||
url="http://www.tldp.org/LDP/abs/abs-guide.pdf">pdf
|
||||
version</ulink> is also available (<ulink
|
||||
url="http://personal.riverusers.com/~thegrendel/abs-guide.pdf"> pdf mirror
|
||||
site</ulink>). See the <ulink
|
||||
url="http://personal.riverusers.com/~thegrendel/Change.log">change
|
||||
log</ulink> for a revision history.</para>
|
||||
|
||||
</abstract>
|
||||
</bookinfo>
|
||||
|
||||
|
@ -660,16 +646,17 @@
|
|||
|
||||
give them <firstterm>execute</firstterm> permission
|
||||
(<userinput>chmod u+rx scriptname</userinput>),
|
||||
then run them to see what happens. Should the source
|
||||
archive not be available, then cut-and-paste from the <ulink
|
||||
then run them to see what happens. Should the <ulink
|
||||
url="http://bash.neuralshortcircuit.com/abs-guide-latest.tar.bz2">source
|
||||
archive</ulink> not be available, then cut-and-paste from the <ulink
|
||||
url="http://www.tldp.org/LDP/abs/abs-guide.html.tar.gz">HTML</ulink> or
|
||||
<ulink url="http://www.tldp.org/LDP/abs/abs-guide.pdf">pdf</ulink>
|
||||
<ulink url="http://bash.neuralshortcircuit.com/abs-guide.pdf">pdf</ulink>
|
||||
rendered versions. Be aware that some of the scripts presented here
|
||||
introduce features before they are explained, and this may require
|
||||
the reader to temporarily skip ahead for enlightenment.</para>
|
||||
|
||||
<para>Unless otherwise noted, <ulink
|
||||
url="mailto:thegrendel@theriver.com">the author</ulink> of this
|
||||
url="mailto:thegrendel.abs@gmail.com">the author</ulink> of this
|
||||
book wrote the example scripts that follow.</para>
|
||||
|
||||
<epigraph>
|
||||
|
@ -1056,12 +1043,23 @@ fi</programlisting>
|
|||
<para><programlisting>echo "A comment will follow." # Comment here.
|
||||
# ^ Note whitespace before #</programlisting></para>
|
||||
|
||||
<para><anchor id="wsbcomm"></para>
|
||||
<para>Comments may also follow <link
|
||||
linkend="whitespaceref">whitespace</link> at the beginning
|
||||
of a line.</para>
|
||||
<para><anchor id="wsbcomm"> Comments may also follow <link
|
||||
linkend="whitespaceref">whitespace</link> at the beginning
|
||||
of a line.</para>
|
||||
<para>
|
||||
<programlisting># A tab precedes this comment.</programlisting>
|
||||
</para>
|
||||
|
||||
<para><anchor id="comminpipe">Comments may even be embedded
|
||||
within a <link linkend="piperef">pipe</link>.</para>
|
||||
<para>
|
||||
<programlisting>initial=( `cat "$startfile" | sed -e '/#/d' | tr -d '\n' |\
|
||||
# Delete lines containing '#' comment character.
|
||||
sed -e 's/\./\. /g' -e 's/_/_ /g'` )
|
||||
# Excerpted from life.sh script</programlisting>
|
||||
</para>
|
||||
|
||||
|
||||
<para><programlisting> # A tab precedes this comment.</programlisting></para>
|
||||
|
||||
<caution><para>A command may not follow a comment on the
|
||||
same line. There is no method of terminating the comment,
|
||||
|
@ -1118,10 +1116,10 @@ echo $(( 2#101011 )) # Base conversion, not a comment.
|
|||
<programlisting>echo hello; echo there
|
||||
|
||||
|
||||
if [ -x "$filename" ]; then # Note that "if" and "then" need whitespace
|
||||
#+ separation. Why?
|
||||
if [ -x "$filename" ]; then # Note the space after the semicolon.
|
||||
#+ ^^
|
||||
echo "File $filename exists."; cp $filename $filename.bak
|
||||
else
|
||||
else # ^^
|
||||
echo "File $filename not found."; touch $filename
|
||||
fi; echo "File test complete."</programlisting>
|
||||
</para>
|
||||
|
@ -1522,7 +1520,8 @@ fi</programlisting>
|
|||
<programlisting>: This is a comment that generates an error, ( if [ $x -eq 3] ).</programlisting>
|
||||
</para>
|
||||
|
||||
<para>The <quote><token>:</token></quote> also serves as a field
|
||||
<para>The <quote><token>:</token></quote> also serves as a <link
|
||||
linkend="fieldref">field</link>
|
||||
separator, in <link
|
||||
linkend="datafilesref1"><filename>/etc/passwd</filename></link>,
|
||||
and in the <link linkend="pathref">$PATH</link> variable.
|
||||
|
@ -1890,12 +1889,12 @@ echo $var2 # 23skidoo</programlisting>
|
|||
</para>
|
||||
<para><anchor id="processref"></para>
|
||||
<para>
|
||||
Definition: A <firstterm>process</firstterm> is
|
||||
an executing program, sometimes referred to as a
|
||||
<firstterm>job</firstterm>.
|
||||
</para>
|
||||
</footnote>
|
||||
of the script in which it appears.</para>
|
||||
<userinput>Definition:</userinput> A
|
||||
<firstterm>process</firstterm> is a currently
|
||||
executing program, sometimes referred to as a
|
||||
<firstterm>job</firstterm>. </para>
|
||||
</footnote>
|
||||
of the script in which it appears.</para>
|
||||
</formalpara>
|
||||
|
||||
</listitem>
|
||||
|
@ -2473,7 +2472,7 @@ cat *.lst | sort | uniq
|
|||
<firstterm>philtre</firstterm> denoted a potion alleged
|
||||
to have magical transformative powers, so does a UNIX
|
||||
<firstterm>filter</firstterm> transform its target in
|
||||
(rougly) analogous fashion. (The coder who comes up with a
|
||||
(roughly) analogous fashion. (The coder who comes up with a
|
||||
<quote>love philtre</quote> that runs on a Linux machine
|
||||
will likely win accolades and honors.)</para></footnote>
|
||||
</para>
|
||||
|
@ -3376,7 +3375,9 @@ echo <Ctl-V><Ctl-J></programlisting></para>
|
|||
<varlistentry>
|
||||
<term><anchor id="whitespaceref">Whitespace</term>
|
||||
<listitem>
|
||||
<formalpara><title>functions as a separator, separating commands or variables.</title>
|
||||
<formalpara>
|
||||
<title>functions as a separator between commands and/or
|
||||
variables.</title>
|
||||
<para>Whitespace consists of either
|
||||
<firstterm>spaces</firstterm>,
|
||||
<firstterm>tabs</firstterm>, <firstterm>blank
|
||||
|
@ -3398,8 +3399,19 @@ echo <Ctl-V><Ctl-J></programlisting></para>
|
|||
sections.</para>
|
||||
|
||||
<para><link linkend="ifsref">$IFS</link>, the special variable
|
||||
separating fields of input to certain commands, defaults
|
||||
to whitespace.</para>
|
||||
separating <firstterm>fields</firstterm> of input to certain
|
||||
commands. It defaults to whitespace.</para>
|
||||
|
||||
<sidebar><para>
|
||||
<anchor id="fieldref"><userinput>Definition:</userinput>
|
||||
A <firstterm>field</firstterm> is a discrete chunk of data
|
||||
expressed as a string of consecutive characters.
|
||||
Separating each field from adjacent fields is either
|
||||
<firstterm>whitespace</firstterm> or some other designated
|
||||
character (often determined by the <token>$IFS</token>).
|
||||
In some contexts, a field may be called a
|
||||
<firstterm>record</firstterm>.
|
||||
</para></sidebar>
|
||||
|
||||
<para><anchor id="quotingws"></para>
|
||||
<para>To preserve <firstterm>whitespace</firstterm>
|
||||
|
@ -3751,10 +3763,11 @@ arch=$(uname -m)</programlisting></para>
|
|||
<emphasis><link linkend="forkref">Child processes</link>
|
||||
cannot export variables back to the parent processes that
|
||||
spawned them.</emphasis></para>
|
||||
<para><anchor id="childref2">Definition: A <firstterm>child
|
||||
process</firstterm> is a subprocess launched by another
|
||||
process, its <link linkend="parentref">parent</link>.</para>
|
||||
</note>
|
||||
<para><anchor id="childref2"><userinput>Definition:</userinput>
|
||||
A <firstterm>child process</firstterm> is a
|
||||
subprocess launched by another process, its <link
|
||||
linkend="parentref">parent</link>.</para>
|
||||
</note>
|
||||
|
||||
|
||||
</listitem>
|
||||
|
@ -4876,7 +4889,7 @@ fi
|
|||
# The very useful "if-grep" construct:
|
||||
# -----------------------------------
|
||||
if grep -q Bash file
|
||||
then echo "File contains at least one occurrence of Bash."
|
||||
then echo "File contains at least one occurrence of Bash."
|
||||
fi
|
||||
|
||||
word=Linux
|
||||
|
@ -4891,8 +4904,8 @@ fi
|
|||
|
||||
|
||||
if COMMAND_WHOSE_EXIT_STATUS_IS_0_UNLESS_ERROR_OCCURRED
|
||||
then echo "Command succeeded."
|
||||
else echo "Command failed."
|
||||
then echo "Command succeeded."
|
||||
else echo "Command failed."
|
||||
fi</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -6894,8 +6907,9 @@ echo "FUNCNAME = $FUNCNAME" # FUNCNAME =
|
|||
</indexterm>
|
||||
<listitem><para>internal field separator</para>
|
||||
|
||||
<para>This variable determines how Bash recognizes fields, or word
|
||||
boundaries, when it interprets character strings.</para>
|
||||
<para>This variable determines how Bash recognizes <link
|
||||
linkend="fieldref">fields</link>, or word boundaries,
|
||||
when it interprets character strings.</para>
|
||||
|
||||
<para><anchor id="ifsws"></para>
|
||||
<para>$IFS defaults to <link
|
||||
|
@ -6982,13 +6996,13 @@ echo "FUNCNAME = $FUNCNAME" # FUNCNAME =
|
|||
</indexterm>
|
||||
<listitem>
|
||||
|
||||
<para>Often set in the <filename>.bashrc</filename> or
|
||||
<filename>/etc/profile</filename> files, this
|
||||
<para>Often set in the <link
|
||||
linkend="sample-bashrc"<filename>.bashrc</filename></link>
|
||||
or <filename>/etc/profile</filename> files, this
|
||||
variable controls collation order in filename
|
||||
expansion and pattern matching. If mishandled,
|
||||
<varname>LC_COLLATE</varname> can cause unexpected results
|
||||
in <link linkend="globbingref">filename
|
||||
globbing</link>.</para>
|
||||
<varname>LC_COLLATE</varname> can cause unexpected results in
|
||||
<link linkend="globbingref">filename globbing</link>.</para>
|
||||
|
||||
<note><para>As of version 2.05 of Bash,
|
||||
filename globbing no longer distinguishes between lowercase
|
||||
|
@ -7138,8 +7152,9 @@ echo "Last command argument processed = $last_cmd_arg"
|
|||
of directories, separated by colons. Normally,
|
||||
the system stores the <varname>$PATH</varname>
|
||||
definition in <filename>/etc/profile</filename>
|
||||
and/or <filename>~/.bashrc</filename> (see <xref
|
||||
linkend="files">).</para>
|
||||
and/or <link
|
||||
linkend="sample-bashrc"><filename>~/.bashrc</filename></link>
|
||||
(see <xref linkend="files">).</para>
|
||||
|
||||
<para><screen><prompt>bash$ </prompt><command>echo $PATH</command>
|
||||
<computeroutput>/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/sbin:/usr/sbin</computeroutput></screen>
|
||||
|
@ -8540,9 +8555,17 @@ echo ${stringZ%%b*c} # a
|
|||
</indexterm>
|
||||
|
||||
<listitem>
|
||||
<para>Replace first match of
|
||||
<para>
|
||||
Replace first <firstterm>match</firstterm> of
|
||||
<replaceable>$substring</replaceable> with
|
||||
<replaceable>$replacement</replaceable>.</para>
|
||||
<replaceable>$replacement</replaceable>.
|
||||
<footnote><para>Note that
|
||||
<replaceable>$substring</replaceable> and
|
||||
<replaceable>$replacement</replaceable> may refer to
|
||||
either <firstterm>literal strings</firstterm> or
|
||||
<firstterm>variables</firstterm>, depending on
|
||||
context. See the first usage example.</para></footnote>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -8563,15 +8586,30 @@ echo ${stringZ%%b*c} # a
|
|||
<para>
|
||||
<programlisting>stringZ=abcABC123ABCabc
|
||||
|
||||
echo ${stringZ/abc/xyz} # xyzABC123ABCabc
|
||||
# Replaces first match of 'abc' with 'xyz'.
|
||||
echo ${stringZ/abc/xyz} # xyzABC123ABCabc
|
||||
# Replaces first match of 'abc' with 'xyz'.
|
||||
|
||||
echo ${stringZ//abc/xyz} # xyzABC123ABCxyz
|
||||
# Replaces all matches of 'abc' with # 'xyz'.
|
||||
echo ${stringZ//abc/xyz} # xyzABC123ABCxyz
|
||||
# Replaces all matches of 'abc' with # 'xyz'.
|
||||
|
||||
echo ---------------
|
||||
echo "$stringZ" # abcABC123ABCabc
|
||||
echo ---------------
|
||||
# The string itself is not altered!
|
||||
|
||||
# Can the match and replacement strings be parameterized?
|
||||
match=abc
|
||||
repl=000
|
||||
echo ${stringZ/$match/$repl} # 000ABC123ABCabc
|
||||
# ^ ^ ^^^
|
||||
echo ${stringZ//$match/$repl} # 000ABC123ABC000
|
||||
# Yes! ^ ^ ^^^ ^^^
|
||||
|
||||
echo
|
||||
|
||||
# What happens if no $replacement string is supplied?
|
||||
echo ${stringZ/abc} # ABC123ABCabc
|
||||
echo ${stringZ//abc} # ABC123ABC
|
||||
echo ${stringZ/abc} # ABC123ABCabc
|
||||
echo ${stringZ//abc} # ABC123ABC
|
||||
# A simple deletion takes place.</programlisting>
|
||||
</para>
|
||||
|
||||
|
@ -12036,9 +12074,16 @@ while read f; do
|
|||
<secondary>let</secondary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>The <command>let</command> command carries out arithmetic
|
||||
operations on variables. In many cases, it functions as a less
|
||||
complex version of <link linkend="exprref">expr</link>.</para>
|
||||
<para>The <command>let</command> command carries out
|
||||
<firstterm>arithmetic</firstterm> operations on variables.
|
||||
|
||||
<footnote><para>Note that <firstterm>let</firstterm>
|
||||
<link linkend="letbad">cannot be used
|
||||
for setting <firstterm>string</firstterm>
|
||||
variables.</link></para></footnote>
|
||||
|
||||
In many cases, it functions as a less complex version
|
||||
of <link linkend="exprref">expr</link>.</para>
|
||||
|
||||
<example id="ex46">
|
||||
<title>Letting <firstterm>let</firstterm> do arithmetic.</title>
|
||||
|
@ -12167,7 +12212,8 @@ eval eval echo $a # d
|
|||
linkend="posparamref">positional parameters</link> that
|
||||
a script sees as the result of a command (<userinput>set
|
||||
`command`</userinput>). The script can then parse the
|
||||
fields of the command output.</para>
|
||||
<link linkend="fieldref">fields</link> of the command
|
||||
output.</para>
|
||||
|
||||
<example id="ex34">
|
||||
<title>Using <firstterm>set</firstterm> with positional
|
||||
|
@ -14997,8 +15043,9 @@ OneYearAgo=$(date --date='1 year ago')</programlisting></para>
|
|||
<secondary>awk</secondary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>A tool for extracting fields from files. It is similar to the
|
||||
<userinput>print $N</userinput> command set in <link
|
||||
<para>A tool for extracting <link
|
||||
linkend="fieldref">fields</link> from files. It is similar
|
||||
to the <userinput>print $N</userinput> command set in <link
|
||||
linkend="awkref">awk</link>, but more limited. It may be
|
||||
simpler to use <firstterm>cut</firstterm> in a script than
|
||||
<firstterm>awk</firstterm>. Particularly important are the
|
||||
|
@ -15100,10 +15147,11 @@ done
|
|||
|
||||
<para>The <command>join</command> command operates on
|
||||
exactly two files, but pastes together only those lines
|
||||
with a common tagged field (usually a numerical label),
|
||||
and writes the result to <filename>stdout</filename>.
|
||||
The files to be joined should be sorted according to the
|
||||
tagged field for the matchups to work properly.</para>
|
||||
with a common tagged <link linkend="fieldref">field</link>
|
||||
(usually a numerical label), and writes the result to
|
||||
<filename>stdout</filename>. The files to be joined should
|
||||
be sorted according to the tagged field for the matchups
|
||||
to work properly.</para>
|
||||
|
||||
<para><programlisting>File: 1.data
|
||||
|
||||
|
@ -15558,8 +15606,9 @@ Here is some text.</programlisting>
|
|||
<term><command><link linkend="awkref">awk</link></command></term>
|
||||
<listitem>
|
||||
<para>Programmable file extractor and formatter, good for
|
||||
manipulating and/or extracting fields (columns) in
|
||||
structured text files. Its syntax is similar to C.</para>
|
||||
manipulating and/or extracting <link
|
||||
linkend="fieldref">fields</link> (columns) in structured
|
||||
text files. Its syntax is similar to C.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -22823,7 +22872,8 @@ mount -o loop /dev/loop0 /mnt # Mount it.
|
|||
to <filename>/aaa/bbb</filename> as the base directory,
|
||||
rather than <filename class="directory">/</filename> as is
|
||||
normally the case. An <command>alias XX 'chroot /aaa/bbb
|
||||
ls'</command> in a user's <filename>~/.bashrc</filename>
|
||||
ls'</command> in a user's <link
|
||||
linkend="sample-bashrc"><filename>~/.bashrc</filename></link>
|
||||
effectively restricts which portion of the filesystem
|
||||
she may run command <quote>XX</quote> on.</para>
|
||||
|
||||
|
@ -22856,12 +22906,14 @@ mount -o loop /dev/loop0 /mnt # Mount it.
|
|||
<secondary>lockfile</secondary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>This utility is part of the <command>procmail</command>
|
||||
<para>This utility is part of the <command>procmail</command>
|
||||
package (<ulink url="http://www.procmail.org">www.procmail.org</ulink>).
|
||||
It creates a <firstterm>lock file</firstterm>, a
|
||||
<firstterm>semaphore</firstterm>
|
||||
<firstterm>semaphore</firstterm> that controls access to
|
||||
a file, device, or resource.</para>
|
||||
|
||||
<footnote><para><anchor id="semaphoreref">Definition:
|
||||
<sidebar><para><anchor id="semaphoreref">
|
||||
<userinput>Definition:</userinput>
|
||||
A <firstterm>semaphore</firstterm> is a flag or
|
||||
signal. (The usage originated in railroading, where a
|
||||
colored flag, lantern, or striped movable arm
|
||||
|
@ -22869,13 +22921,13 @@ mount -o loop /dev/loop0 /mnt # Mount it.
|
|||
particular track was in use and therefore unavailable
|
||||
for another train.) A UNIX process can check the
|
||||
appropriate semaphore to determine whether a particular
|
||||
resource is available/accessible.</para></footnote>
|
||||
resource is available/accessible.</para></sidebar>
|
||||
|
||||
file that controls access to a file, device, or resource.
|
||||
The lock file serves as a flag that this particular
|
||||
file, device, or resource is in use by a process (it is
|
||||
<quote>busy</quote>), and this permits only restricted
|
||||
access (or no access) to other processes.</para>
|
||||
<para>The lock file serves as a flag that this particular
|
||||
file, device, or resource is in use by a process (and
|
||||
is therefore <quote>busy</quote>). The presence of a
|
||||
lock file permits only restricted access (or no access)
|
||||
to other processes.</para>
|
||||
|
||||
<para><programlisting>lockfile /home/bozo/lockfiles/$0.lock
|
||||
# Creates a write-protected lockfile prefixed with the name of the script.
|
||||
|
@ -22887,7 +22939,7 @@ lockfile /home/bozo/lockfiles/${0##*/}.lock
|
|||
system mail folders from simultaneously being changed
|
||||
by multiple users, indicating that a modem port
|
||||
is being accessed, and showing that an instance of
|
||||
<application>Netscape</application> is using its cache.
|
||||
<application>Firefox</application> is using its cache.
|
||||
Scripts may check for the existence of a lock file created
|
||||
by a certain process to check if that process is running.
|
||||
Note that if a script attempts to create a lock file that
|
||||
|
@ -24213,10 +24265,10 @@ echo a111b | gawk '/a1+b/'
|
|||
<userinput>0-9A-Fa-f</userinput>.</para>
|
||||
|
||||
<important>
|
||||
|
||||
<para>POSIX character classes generally require quoting
|
||||
or <link linkend="dblbrackets">double brackets</link>
|
||||
([[ ]]).</para>
|
||||
</important>
|
||||
|
||||
<para>
|
||||
<screen><prompt>bash$ </prompt><userinput>grep [[:digit:]] test.file</userinput>
|
||||
|
@ -24224,6 +24276,14 @@ echo a111b | gawk '/a1+b/'
|
|||
</screen>
|
||||
</para>
|
||||
|
||||
<para><programlisting># ...
|
||||
if [[ $arow =~ [[:digit:]] ]] # Numerical input?
|
||||
then # POSIX char class
|
||||
if [[ $acol =~ [[:alpha:]] ]] # Number followed by a letter? Illegal!
|
||||
# ...
|
||||
# From ktour.sh example script.</programlisting>
|
||||
</para>
|
||||
|
||||
<para>These character classes may even be used with <link
|
||||
linkend="globbingref">globbing</link>, to a limited
|
||||
extent.</para>
|
||||
|
@ -24234,10 +24294,9 @@ echo a111b | gawk '/a1+b/'
|
|||
</screen>
|
||||
</para>
|
||||
|
||||
<para>To see POSIX character classes used in scripts, refer to
|
||||
<para>POSIX character classes are used in
|
||||
<xref linkend="ex49"> and <xref linkend="lowercase">.</para>
|
||||
|
||||
</important>
|
||||
|
||||
</listitem>
|
||||
|
||||
|
@ -24297,7 +24356,8 @@ echo a111b | gawk '/a1+b/'
|
|||
<anchor id="wdotfilewc">There are important limitations on wild
|
||||
card characters in globbing, however. Strings containing
|
||||
<replaceable>*</replaceable> will not match filenames that
|
||||
start with a dot, as, for example, <filename>.bashrc</filename>.
|
||||
start with a dot, as, for example, <link
|
||||
linkend="sample-bashrc"><filename>.bashrc</filename></link>.
|
||||
|
||||
<footnote>
|
||||
<para>
|
||||
|
@ -25230,7 +25290,8 @@ echo "$nr files totaling $totalSize bytes"</programlisting>
|
|||
<firstterm>subshell</firstterm>.</para>
|
||||
|
||||
<sidebar>
|
||||
<para>Definition: A <firstterm>subshell</firstterm> is a
|
||||
<para><userinput>Definition:</userinput>
|
||||
A <firstterm>subshell</firstterm> is a
|
||||
<link linkend="childref2">child process</link> launched by a
|
||||
shell (or <firstterm>shell script</firstterm>).</para>
|
||||
</sidebar>
|
||||
|
@ -25334,7 +25395,7 @@ but is shown here for illustrative purposes.</programlisting>
|
|||
|
||||
<sidebar>
|
||||
<para><anchor id="scoperef"></para>
|
||||
<para><emphasis>Definition:</emphasis> The
|
||||
<para><userinput>Definition:</userinput> The
|
||||
<firstterm>scope</firstterm> of a variable is the
|
||||
context in which it has meaning, in which it has a
|
||||
<firstterm>value</firstterm> that can be referenced. For
|
||||
|
@ -26285,6 +26346,11 @@ Function () # This doesn't work.
|
|||
# Thanks, S.C.</programlisting>
|
||||
</para>
|
||||
|
||||
<note><para>Emmanuel Rouat's <link
|
||||
linkend="sample-bashrc">sample <filename>bashrc</filename>
|
||||
file</link> contains some instructive examples of
|
||||
functions.</para></note>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -26483,7 +26549,7 @@ exit 0 # This script will not exit normally.
|
|||
more than a keyboard shortcut, an abbreviation, a means of
|
||||
avoiding typing a long command sequence. If, for example,
|
||||
we include <command>alias lm="ls -l | more"</command> in
|
||||
the <link linkend="filesref1"><filename>~/.bashrc</filename>
|
||||
the <link linkend="sample-bashrc"><filename>~/.bashrc</filename>
|
||||
file</link>, then each <userinput>lm</userinput>
|
||||
<footnote><para> ... as the first word of a command string.
|
||||
Obviously, an alias is only meaningful at the
|
||||
|
@ -28358,6 +28424,14 @@ fi # Aborts with an error message.
|
|||
</example>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><anchor id="letbad"></para>
|
||||
<para>Attempting to use <link linkend="letref">let</link>
|
||||
to set string variables.</para>
|
||||
<para><programlisting>let "a = hello, you"
|
||||
echo "$a" # 0</programlisting></para>
|
||||
</listitem>
|
||||
|
||||
|
||||
<listitem>
|
||||
<para><anchor id="failquote"></para>
|
||||
|
@ -28433,10 +28507,11 @@ fi
|
|||
|
||||
|
||||
<listitem>
|
||||
<para>Using Bash-specific functionality in a Bourne shell script
|
||||
<para>Using Bash-specific functionality in a <link
|
||||
linkend="bashdef">Bourne shell</link> script
|
||||
(<userinput>#!/bin/sh</userinput>) on a non-Linux machine
|
||||
<link linkend="binsh">may cause unexpected behavior</link>. A
|
||||
Linux system usually aliases <command>sh</command> to
|
||||
<link linkend="binsh">may cause unexpected behavior</link>.
|
||||
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>
|
||||
|
||||
|
@ -30444,8 +30519,8 @@ echo "User entered: "$answer""</programlisting>
|
|||
utilities has accelerated the trend.</para>
|
||||
|
||||
<para><anchor id="bashcompat"></para>
|
||||
<para>Bash has certain features that the traditional Bourne shell
|
||||
lacks. Among these are:
|
||||
<para>Bash has certain features that the traditional <link
|
||||
linkend="bashdef">Bourne shell</link> lacks. Among these are:
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
|
@ -30888,7 +30963,8 @@ echo $a # 6</programlisting>
|
|||
<title>About the Author</title>
|
||||
<subtitle>Who is this guy anyhow?</subtitle>
|
||||
|
||||
<para>The author claims no credentials or special qualifications,
|
||||
<para><anchor id="nocreds">The author claims no credentials or
|
||||
special qualifications,
|
||||
<footnote><para>In fact, he is a school dropout
|
||||
and has no formal credentials or qualifications
|
||||
whatsoever.</para></footnote>
|
||||
|
@ -30896,7 +30972,7 @@ echo $a # 6</programlisting>
|
|||
<footnote><para>Those who can, do. Those who can't . . . get an
|
||||
MCSE.</para></footnote>
|
||||
This book is somewhat of a departure from his other major work,
|
||||
<ulink url="http://personal.riverusers.com/~thegrendel/hmw60.zip">
|
||||
<ulink url="http://bash.neuralshortcircuit.com/hmw60.zip">
|
||||
HOW-2 Meet Women: The Shy Man's Guide to
|
||||
Relationships</ulink>. He has also written the <ulink
|
||||
url="http://tldp.org/HOWTO/Software-Building-HOWTO.html">Software-Building
|
||||
|
@ -30914,7 +30990,7 @@ echo $a # 6</programlisting>
|
|||
Scrabble® adjudicator, the <ulink
|
||||
url="http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz">yawl</ulink>
|
||||
word gaming list package, and the <ulink
|
||||
url="http://personal.riverusers.com/~thegrendel/qky.README.html">Quacky</ulink>
|
||||
url="http://bash.neuralshortcircuit.com/qky.README.html">Quacky</ulink>
|
||||
anagramming gaming package. He got off to a rather shaky start in the
|
||||
computer game -- programming FORTRAN IV on a CDC 3800 --
|
||||
and is not the least bit nostalgic for those days.</para>
|
||||
|
@ -30934,7 +31010,7 @@ echo $a # 6</programlisting>
|
|||
<sect1 id="wherehelp">
|
||||
<title>Where to Go For Help</title>
|
||||
|
||||
<para><ulink url="mailto:thegrendel@theriver.com">The author</ulink>
|
||||
<para><ulink url="mailto:thegrendel.abs@gmail.com">The author</ulink>
|
||||
will sometimes, if not too busy (and in a good mood),
|
||||
answer general scripting questions.
|
||||
<footnote><para>E-mails from certain spam-infested TLDs
|
||||
|
@ -31130,6 +31206,7 @@ echo $a # 6</programlisting>
|
|||
<para>Andreas Abraham sent in a long list of typographical
|
||||
errors and other corrections. Special thanks!</para>
|
||||
|
||||
|
||||
<para>Others contributing scripts, making helpful suggestions, and
|
||||
pointing out errors were Gabor Kiss, Leopold Toetsch,
|
||||
Peter Tillier, Marcus Berglof, Tony Richardson, Nick Drage
|
||||
|
@ -31279,7 +31356,7 @@ echo $a # 6</programlisting>
|
|||
familiarity with <link linkend="sedref"><firstterm>sed</firstterm>
|
||||
and <firstterm>awk</firstterm></link>. This is the standard
|
||||
tutorial. It includes an excellent introduction to
|
||||
<quote>regular expressions.</quote> Recommended.</para>
|
||||
<firstterm>Regular Expressions</firstterm>. Recommended.</para>
|
||||
<para>*</para>
|
||||
</abstract>
|
||||
</biblioentry>
|
||||
|
@ -31315,9 +31392,10 @@ echo $a # 6</programlisting>
|
|||
<year>2002</year>
|
||||
</copyright>
|
||||
<isbn>0-596-00343-9</isbn>
|
||||
<abstract><para>This excellent sys admin manual has a decent introduction to shell
|
||||
scripting for sys administrators and does a thorough job of explaining the
|
||||
startup and initialization scripts.</para>
|
||||
<abstract><para>This excellent manual provides a decent introduction
|
||||
to shell scripting from a sys admin point of view. It includes
|
||||
comprehensive explanations of the startup and initialization
|
||||
scripts in a UNIX system.</para>
|
||||
<para>*</para>
|
||||
<para><anchor id="kochanref"></para>
|
||||
</abstract>
|
||||
|
@ -31779,6 +31857,14 @@ echo $a # 6</programlisting>
|
|||
</abstract>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry>
|
||||
<abstract>
|
||||
<para><ulink url="http://bashcookbook.com/bashinfo/">Examples</ulink>
|
||||
from the <citetitle pubwork="book">The Bash Scripting
|
||||
Cookbook</citetitle>, by Albing, Vossen, and Newham.</para>
|
||||
</abstract>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry>
|
||||
<abstract>
|
||||
<para>Example shell scripts at <ulink
|
||||
|
@ -32417,6 +32503,17 @@ echo $a # 6</programlisting>
|
|||
<programlisting>&homework;</programlisting>
|
||||
</example>
|
||||
|
||||
<para<anchor id="ktour0"></para>
|
||||
<example id="ktour">
|
||||
<title>The Knight's Tour</title>
|
||||
<programlisting>&ktour;</programlisting>
|
||||
</example>
|
||||
|
||||
<example id="msquare">
|
||||
<title>Magic Squares</title>
|
||||
<programlisting>&msquare;</programlisting>
|
||||
</example>
|
||||
|
||||
<example id="usegetopt">
|
||||
<title>An alternate version of the
|
||||
<link linkend="getoptsimple">getopt-simple.sh</link> script</title>
|
||||
|
@ -33454,7 +33551,8 @@ pattern=BEGIN
|
|||
a few of these here - the ones most useful in shell scripts.</para>
|
||||
|
||||
<para>Awk breaks each line of input passed to it into
|
||||
<firstterm>fields</firstterm>. By default, a field
|
||||
<anchor id="fieldref2">
|
||||
<link linkend="fieldref">fields</link>. By default, a field
|
||||
is a string of consecutive characters delimited by <link
|
||||
linkend="whitespaceref">whitespace</link>, though there are options
|
||||
for changing this. Awk parses and operates on each separate
|
||||
|
@ -35082,16 +35180,20 @@ var=$(history); echo "$var" # $var is empty.
|
|||
<para>
|
||||
<literallayout>
|
||||
On a dingy side street in a run-down section of Hoboken, New Jersey,
|
||||
there sits a nondescript squat two-story brick building
|
||||
with a inscription incised on a marble plate in its wall:
|
||||
there sits a nondescript squat two-story brick building with an inscription
|
||||
incised on a marble plate in its wall:
|
||||
|
||||
<computeroutput>Bash Scripting Hall of Fame</computeroutput>.
|
||||
|
||||
Inside, among various dusty uninteresting exhibits is a corroding,
|
||||
cobweb-festooned brass plaque inscribed with a short, very short
|
||||
list of those few persons who have successfully mastered the material
|
||||
in the <firstterm>Advanced Bash Scripting Guide</firstterm>,
|
||||
as evidenced by their performance on the following Exercise sections. . . .
|
||||
in the <firstterm>Advanced Bash Scripting Guide</firstterm>, as evidenced by their performance
|
||||
on the following Exercise sections.
|
||||
|
||||
(Alas, the author of the <firstterm>ABS Guide</firstterm> is not represented among the exhibits.
|
||||
This is possibly due to malicious rumors about <link linkend="nocreds">lack of credentials</link> and
|
||||
<link linkend="ktour0">deficient scripting skills</link>.)
|
||||
</literallayout>
|
||||
</para>
|
||||
|
||||
|
@ -35647,8 +35749,8 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUM</pro
|
|||
with <firstterm>comma-separated values</firstterm>
|
||||
(CSVs). Other applications often need to parse these
|
||||
files.</para>
|
||||
<para>Given a data file with comma-separated fields,
|
||||
of the form:
|
||||
<para>Given a data file with comma-separated <link
|
||||
linkend="fieldref">fields</link>, of the form:
|
||||
<programlisting>Jones,Bill,235 S. Williams St.,Denver,CO,80221,(303) 244-7989
|
||||
Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612
|
||||
...</programlisting>
|
||||
|
@ -35990,13 +36092,13 @@ s c r i p t</programlisting></para>
|
|||
<listitem>
|
||||
<para>Do a hex(adecimal) dump on a binary file
|
||||
specified as an argument. The output should be in neat
|
||||
tabular fields, with the first field showing the address,
|
||||
each of the next 8 fields a 4-byte hex number, and the final
|
||||
field the ASCII equivalent of the previous 8 fields.</para>
|
||||
<para>The obvious followup to this is to extend the hex dump
|
||||
script into a disassembler. Using a lookup table, or some other
|
||||
clever gimmick, convert the hex values into 80x86 op
|
||||
codes.</para>
|
||||
tabular <link linkend="fieldref">fields</link>, with the
|
||||
first field showing the address, each of the next 8 fields a
|
||||
4-byte hex number, and the final field the ASCII equivalent
|
||||
of the previous 8 fields.</para> <para>The obvious
|
||||
followup to this is to extend the hex dump script into a
|
||||
disassembler. Using a lookup table, or some other clever
|
||||
gimmick, convert the hex values into 80x86 op codes.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -36600,6 +36702,11 @@ thegrendel@theriver.com</programlisting></para>
|
|||
<entry>23 Nov 2008</entry>
|
||||
<entry>FARKLEBERRY release: Minor update.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>5.6</option></entry>
|
||||
<entry>26 Jan 2009</entry>
|
||||
<entry>WORCESTERBERRY release: Minor update.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
@ -36608,34 +36715,43 @@ thegrendel@theriver.com</programlisting></para>
|
|||
</appendix> <!-- End Revision History appendix -->
|
||||
|
||||
<appendix id="mirrorsites">
|
||||
<title>Mirror Sites</title>
|
||||
<title>Download and Mirror Sites</title>
|
||||
|
||||
<para><ulink
|
||||
url="http://thegrendel.150m.com/abs-guide-5.5.tar.bz2">
|
||||
The latest update of this document</ulink>, as an archived
|
||||
<quote>tarball</quote>
|
||||
including both the SGML source and rendered HTML, may
|
||||
be downloaded from the <ulink
|
||||
url="http://personal.riverusers.com/~thegrendel/abs-guide-5.5.tar.bz2">author's
|
||||
home site</ulink>.</para>
|
||||
<para><anchor id="where_tarball"></para>
|
||||
|
||||
<para>The main mirror site for this document is the <ulink
|
||||
<para>The latest update of this document, as an archived,
|
||||
<link linkend="bzipref">bzip2-ed</link>
|
||||
<quote>tarball</quote> including both the SGML source
|
||||
and rendered HTML, may be downloaded from the <ulink
|
||||
url="http://bash.neuralshortcircuit.com/abs-guidelatest.tar.bz2">author's
|
||||
home site</ulink>).
|
||||
|
||||
A <ulink
|
||||
url="http://bash.neuralshortcircuit.com/abs-guide.pdf">
|
||||
pdf version</ulink> is also available.
|
||||
|
||||
The <ulink
|
||||
url="http://bash.neuralshortcircuit.com/Change.log">change
|
||||
log</ulink> gives a detailed revision history.
|
||||
The <emphasis>ABS Guide</emphasis> even has <ulink
|
||||
url="http://freshmeat.net/projects/advancedbashscriptingguide/">
|
||||
its own <filename>freshmeat.net</filename> page</ulink> to keep
|
||||
track of major updates, user comments, and popularity ratings
|
||||
for the project.</para>
|
||||
|
||||
<para>The main hosting site for this document is the <ulink
|
||||
url="http://www.tldp.org/LDP/abs/">Linux Documentation Project</ulink>,
|
||||
which maintains many other Guides and HOWTOs as well.</para>
|
||||
|
||||
|
||||
<para>Yet another mirror site for this document is
|
||||
<ulink url="http://www.morethan.org">morethan.org</ulink>.</para>
|
||||
|
||||
<para>You can download the <emphasis>pdf</emphasis> version
|
||||
<ulink
|
||||
url="http://personal.riverusers.com/~thegrendel/abs-guide.pdf">
|
||||
here</ulink>.</para>
|
||||
<para>Many thanks to Ronny Bangsund for donating <ulink
|
||||
url="http://bash.neuralshortcircuit.com/">server space</ulink> to host
|
||||
this project.</para>
|
||||
|
||||
|
||||
</appendix> <!-- Mirror Sites appendix -->
|
||||
|
||||
|
||||
|
||||
<appendix id="todolist">
|
||||
<title>To Do List</title>
|
||||
|
||||
|
@ -36643,7 +36759,8 @@ thegrendel@theriver.com</programlisting></para>
|
|||
<listitem>
|
||||
<para>A comprehensive survey of <link
|
||||
linkend="bashcompat">incompatibilities</link> between
|
||||
Bash and the classic Bourne shell.</para>
|
||||
Bash and the classic <link linkend="bashdef">Bourne
|
||||
shell</link>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
@ -36778,7 +36895,7 @@ distributors, or any of its associated software or documentation.</programlistin
|
|||
|
||||
<para>The commercial print and other rights to this book are
|
||||
available. Please contact <ulink
|
||||
url="mailto:thegrendel@theriver.com">the author</ulink> if
|
||||
url="mailto:thegrendel.abs@gmail.com">the author</ulink> if
|
||||
interested.</para>
|
||||
|
||||
<para>The author produced this book in a manner consistent with the
|
||||
|
|
|
@ -16,7 +16,7 @@ grep -v 'ed$' # no past tense verbs
|
|||
# Uses "anagram" utility
|
||||
#+ that is part of the author's "yawl" word list package.
|
||||
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
|
||||
# http://personal.riverusers.com/~thegrendel/yawl-0.3.2.tar.gz
|
||||
# http://bash.neuralshortcircuit.com/yawl-0.3.2.tar.gz
|
||||
|
||||
exit 0 # End of code.
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# Uses "anagram" utility
|
||||
#+ that is part of the author's "yawl" word list package.
|
||||
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
|
||||
# http://personal.riverusers.com/~thegrendel/yawl-0.3.2.tar.gz
|
||||
# http://bash.neuralshortcircuit.com/yawl-0.3.2.tar.gz
|
||||
|
||||
E_NOARGS=66
|
||||
E_BADARG=67
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# ==> Used in ABS Guide with the script author's permission.
|
||||
# ==> Comments added by ABS Guide author.
|
||||
|
||||
NOARGS=65
|
||||
NOARGS=85
|
||||
PN=`basename "$0"` # Program name
|
||||
VER=`echo '$Revision$' | cut -d' ' -f2` # ==> VER=1.2
|
||||
|
||||
|
@ -31,10 +31,10 @@ A number may be
|
|||
hexadecimal (base 16) starting with 0x (i.e. 0xc)
|
||||
decimal otherwise (i.e. 12)" >&2
|
||||
exit $NOARGS
|
||||
} # ==> Function to print usage message.
|
||||
} # ==> Prints usage message.
|
||||
|
||||
Msg () {
|
||||
for i # ==> in [list] missing.
|
||||
for i # ==> in [list] missing. Why?
|
||||
do echo "$PN: $i" >&2
|
||||
done
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ PrintBases () {
|
|||
continue;;
|
||||
esac
|
||||
|
||||
# Remove prefix, convert hex digits to uppercase (bc needs this)
|
||||
# Remove prefix, convert hex digits to uppercase (bc needs this).
|
||||
number=`echo "$i" | sed -e 's:^0[bBxX]::' | tr '[a-f]' '[A-F]'`
|
||||
# ==> Uses ":" as sed separator, rather than "/".
|
||||
|
||||
|
@ -89,15 +89,15 @@ do
|
|||
--) shift; break;;
|
||||
-h) Usage;; # ==> Help message.
|
||||
-*) Usage;;
|
||||
*) break;; # first number
|
||||
esac # ==> More error checking for illegal input might be useful.
|
||||
*) break;; # First number
|
||||
esac # ==> Error checking for illegal input might be appropriate.
|
||||
shift
|
||||
done
|
||||
|
||||
if [ $# -gt 0 ]
|
||||
then
|
||||
PrintBases "$@"
|
||||
else # read from stdin
|
||||
else # Read from stdin.
|
||||
while read line
|
||||
do
|
||||
PrintBases $line
|
||||
|
@ -105,4 +105,4 @@ else # read from stdin
|
|||
fi
|
||||
|
||||
|
||||
exit 0
|
||||
exit
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,7 +20,7 @@ DICT=/usr/share/dict/word.lst
|
|||
#+ download the author's "yawl" word list package.
|
||||
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
|
||||
# or
|
||||
# http://personal.riverusers.com/~thegrendel/yawl-0.3.2.tar.gz
|
||||
# http://bash.neuralshortcircuit.com/yawl-0.3.2.tar.gz
|
||||
|
||||
|
||||
if [ -z "$1" ] # If no word pattern specified
|
||||
|
|
|
@ -144,6 +144,12 @@ echo $diff
|
|||
|
||||
exit 0
|
||||
|
||||
# Exercise:
|
||||
# --------
|
||||
# If given only one command-line parameter, have the script
|
||||
#+ use today's date as the second.
|
||||
|
||||
|
||||
# Compare this script with
|
||||
#+ the implementation of Gauss' Formula in a C program at
|
||||
#+ http://buschencrew.hypermart.net/software/datedif
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# empty-array.sh
|
||||
|
||||
# Thanks to Stephane Chazelas for the original example,
|
||||
#+ and to Michael Zick, Omair Eshkenazi, for extending it.
|
||||
#+ and to Michael Zick and Omair Eshkenazi, for extending it.
|
||||
# And to Nathan Coulter for clarifications and corrections.
|
||||
|
||||
|
||||
|
@ -115,11 +115,12 @@ echo "Elements in array8: ${array8[@]}"
|
|||
#+ that element disappears in the resulting assignment.
|
||||
# However, if the expansion is in quotes, the null elements remain.
|
||||
|
||||
# Michael Zick: Question, are those strings hard or soft quotes?
|
||||
# Nathan Coulter: There is no such thing as "soft quotes."
|
||||
# What's really happening is that
|
||||
#+ the pattern matching happens after all the other expansions of [word]
|
||||
#+ in cases like ${parameter#word}.
|
||||
# Michael Zick: Question, are those strings hard or soft quotes?
|
||||
# Nathan Coulter: There is no such thing as "soft quotes."
|
||||
#! What's really happening is that
|
||||
#!+ the pattern matching happens after
|
||||
#!+ all the other expansions of [word]
|
||||
#!+ in cases like ${parameter#word}.
|
||||
|
||||
|
||||
zap='new*'
|
||||
|
|
|
@ -1,28 +1,30 @@
|
|||
#!/bin/bash
|
||||
# Killing ppp to force a log-off.
|
||||
# For dialup connection, of course.
|
||||
|
||||
# Script should be run as root user.
|
||||
|
||||
killppp="eval kill -9 `ps ax | awk '/ppp/ { print $1 }'`"
|
||||
# -------- process ID of ppp -------
|
||||
|
||||
$killppp # This variable is now a command.
|
||||
|
||||
|
||||
# The following operations must be done as root user.
|
||||
|
||||
chmod 666 /dev/ttyS3 # Restore read+write permissions, or else what?
|
||||
# Since doing a SIGKILL on ppp changed the permissions on the serial port,
|
||||
#+ we restore permissions to previous state.
|
||||
|
||||
rm /var/lock/LCK..ttyS3 # Remove the serial port lock file. Why?
|
||||
|
||||
# Note:
|
||||
SERPORT=ttyS3
|
||||
# Depending on the hardware and even the kernel version,
|
||||
#+ the modem port on your machine may be different --
|
||||
#+ /dev/ttyS1 or /dev/ttyS2.
|
||||
|
||||
exit 0
|
||||
|
||||
killppp="eval kill -9 `ps ax | awk '/ppp/ { print $1 }'`"
|
||||
# -------- process ID of ppp -------
|
||||
|
||||
$killppp # This variable is now a command.
|
||||
|
||||
|
||||
# The following operations must be done as root user.
|
||||
|
||||
chmod 666 /dev/$SERPORT # Restore r+w permissions, or else what?
|
||||
# Since doing a SIGKILL on ppp changed the permissions on the serial port,
|
||||
#+ we restore permissions to previous state.
|
||||
|
||||
rm /var/lock/LCK..$SERPORT # Remove the serial port lock file. Why?
|
||||
|
||||
exit $?
|
||||
|
||||
# Exercises:
|
||||
# ---------
|
||||
|
|
|
@ -102,7 +102,7 @@ Optional environment variables
|
|||
Additional documentation
|
||||
Download the archived set of scripts
|
||||
explaining and illustrating the function contained within this script.
|
||||
http://personal.riverusers.com/mszick_clf.tar.bz2
|
||||
http://bash.neuralshortcircuit.com/mszick_clf.tar.bz2
|
||||
|
||||
|
||||
Study notes
|
||||
|
|
|
@ -0,0 +1,610 @@
|
|||
#!/bin/bash
|
||||
# ktour.sh
|
||||
|
||||
# author: mendel cooper
|
||||
# reldate: 12 Jan 2009
|
||||
# license: public domain
|
||||
# (Not much sense in GPLing something that's pretty much in the common
|
||||
#+ domain anyhow.)
|
||||
|
||||
###################################################################
|
||||
# The Knight's Tour, a classic problem. #
|
||||
# ===================================== #
|
||||
# The knight must move onto every square of the chess board, #
|
||||
# but cannot revisit any square he has already visited. #
|
||||
# #
|
||||
# And just why is Sir Knight unwelcome for a return visit? #
|
||||
# Could it be that he has a habit of partying into the wee hours #
|
||||
#+ of the morning? #
|
||||
# Possibly he leaves pizza crusts in the bed, empty beer bottles #
|
||||
#+ all over the floor, and clogs the plumbing. ... #
|
||||
# #
|
||||
# ------------------------------------------------------------- #
|
||||
# #
|
||||
# Usage: ktour.sh [start-square] [stupid] #
|
||||
# #
|
||||
# Note that start-square can be a square number #
|
||||
#+ in the range 0 - 63 ... or #
|
||||
# a square designator in conventional chess notation, #
|
||||
# such as a1, f5, h3, etc. #
|
||||
# #
|
||||
# If start-square-number not supplied, #
|
||||
#+ then starts on a random square somewhere on the board. #
|
||||
# #
|
||||
# "stupid" as second parameter sets the stupid strategy. #
|
||||
# #
|
||||
# Examples: #
|
||||
# ktour.sh 23 starts on square #23 (h3) #
|
||||
# ktour.sh g6 stupid starts on square #46, #
|
||||
# using "stupid" (non-Warnsdorff) strategy. #
|
||||
###################################################################
|
||||
|
||||
DEBUG= # Set this to echo debugging info to stdout.
|
||||
SUCCESS=0
|
||||
FAIL=99
|
||||
BADMOVE=-999
|
||||
FAILURE=1
|
||||
LINELEN=21 # How many moves to display per line.
|
||||
# ---------------------------------------- #
|
||||
# Board array params
|
||||
ROWS=8 # 8 x 8 board.
|
||||
COLS=8
|
||||
let "SQUARES = $ROWS * $COLS"
|
||||
let "MAX = $SQUARES - 1"
|
||||
MIN=0
|
||||
# 64 squares on board, indexed from 0 to 63.
|
||||
|
||||
VISITED=1
|
||||
UNVISITED=-1
|
||||
UNVSYM="##"
|
||||
# ---------------------------------------- #
|
||||
# Global variables.
|
||||
startpos= # Starting position (square #, 0 - 63).
|
||||
currpos= # Current position.
|
||||
movenum= # Move number.
|
||||
CRITPOS=37 # Have to patch for f5 starting position!
|
||||
|
||||
declare -i board
|
||||
# Use a one-dimensional array to simulate a two-dimensional one.
|
||||
# This can make life difficult and result in ugly kludges; see below.
|
||||
declare -i moves # Offsets from current knight position.
|
||||
|
||||
|
||||
initialize_board ()
|
||||
{
|
||||
local idx
|
||||
|
||||
for idx in {0..63}
|
||||
do
|
||||
board[$idx]=$UNVISITED
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
print_board ()
|
||||
{
|
||||
local idx
|
||||
|
||||
echo " _____________________________________"
|
||||
for row in {7..0} # Reverse order of rows ...
|
||||
do #+ so it prints in chessboard order.
|
||||
let "rownum = $row + 1" # Start numbering rows at 1.
|
||||
echo -n "$rownum |" # Mark board edge with border and
|
||||
for column in {0..7} #+ "algebraic notation."
|
||||
do
|
||||
let "idx = $ROWS*$row + $column"
|
||||
if [ ${board[idx]} -eq $UNVISITED ]
|
||||
then
|
||||
echo -n "$UNVSYM " ##
|
||||
else # Mark square with move number.
|
||||
printf "%02d " "${board[idx]}"; echo -n " "
|
||||
fi
|
||||
done
|
||||
echo -e -n "\b\b\b|" # \b is a backspace.
|
||||
echo # -e enables echoing escaped chars.
|
||||
done
|
||||
|
||||
echo " -------------------------------------"
|
||||
echo " a b c d e f g h"
|
||||
}
|
||||
|
||||
|
||||
|
||||
failure()
|
||||
{ # Whine, then bail out.
|
||||
echo
|
||||
print_board
|
||||
echo
|
||||
echo " Waah!!! Ran out of squares to move to!"
|
||||
echo -n " Knight's Tour attempt ended"
|
||||
echo " on $(to_algebraic $currpos) [square #$currpos]"
|
||||
echo " after just $movenum moves!"
|
||||
echo
|
||||
exit $FAIL
|
||||
}
|
||||
|
||||
|
||||
|
||||
xlat_coords () # Translate x/y coordinates to board position
|
||||
{ #+ (board-array element #).
|
||||
# For user input of starting board position as x/y coords.
|
||||
# This function not used in initial release of ktour.sh.
|
||||
# May be used in an updated version, for compatibility with
|
||||
#+ standard implementation of the Knight's Tour in C, Python, etc.
|
||||
if [ -z "$1" -o -z "$2" ]
|
||||
then
|
||||
return $FAIL
|
||||
fi
|
||||
|
||||
local xc=$1
|
||||
local yc=$2
|
||||
|
||||
let "board_index = $xc * $ROWS + yc"
|
||||
|
||||
if [ $board_index -lt $MIN -o $board_index -gt $MAX ]
|
||||
then
|
||||
return $FAIL # Strayed off the board!
|
||||
else
|
||||
return $board_index
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
to_algebraic () # Translate board position (board-array element #)
|
||||
{ #+ to standard algebraic notation used by chess players.
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
return $FAIL
|
||||
fi
|
||||
|
||||
local element_no=$1 # Numerical board position.
|
||||
local col_arr=( a b c d e f g h )
|
||||
local row_arr=( 1 2 3 4 5 6 7 8 )
|
||||
|
||||
let "row_no = $element_no / $ROWS"
|
||||
let "col_no = $element_no % $ROWS"
|
||||
t1=${col_arr[col_no]}; t2=${row_arr[row_no]}
|
||||
local apos=$t1$t2 # Concatenate.
|
||||
echo $apos
|
||||
}
|
||||
|
||||
|
||||
|
||||
from_algebraic () # Translate standard algebraic chess notation
|
||||
{ #+ to numerical board position (board-array element #).
|
||||
# Or recognize numerical input & return it unchanged.
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
return $FAIL
|
||||
fi # If no command-line arg, then will default to random start pos.
|
||||
|
||||
local ix
|
||||
local ix_count=0
|
||||
local b_index # Board index [0-63]
|
||||
local alpos="$1"
|
||||
|
||||
arow=${alpos:0:1} # position = 0, length = 1
|
||||
acol=${alpos:1:1}
|
||||
|
||||
if [[ $arow =~ [[:digit:]] ]] # Numerical input?
|
||||
then # POSIX char class
|
||||
if [[ $acol =~ [[:alpha:]] ]] # Number followed by a letter? Illegal!
|
||||
then return $FAIL
|
||||
else if [ $alpos -gt $MAX ] # Off board?
|
||||
then return $FAIL
|
||||
else return $alpos # Return digit(s) unchanged . . .
|
||||
fi #+ if within range.
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $acol -eq $MIN || $acol -gt $ROWS ]]
|
||||
then # Outside of range 1 - 8?
|
||||
return $FAIL
|
||||
fi
|
||||
|
||||
for ix in a b c d e f g h
|
||||
do # Convert column letter to column number.
|
||||
if [ "$arow" = "$ix" ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
((ix_count++)) # Find index count.
|
||||
done
|
||||
|
||||
((acol--)) # Decrementing converts to zero-based array.
|
||||
let "b_index = $ix_count + $acol * $ROWS"
|
||||
|
||||
if [ $b_index -gt $MAX ] # Off board?
|
||||
then
|
||||
return $FAIL
|
||||
fi
|
||||
|
||||
return $b_index
|
||||
|
||||
}
|
||||
|
||||
|
||||
generate_moves () # Calculate all valid knight moves,
|
||||
{ #+ relative to current position ($1),
|
||||
#+ and store in ${moves} array.
|
||||
local kt_hop=1 # One square :: short leg of knight move.
|
||||
local kt_skip=2 # Two squares :: long leg of knight move.
|
||||
local valmov=0 # Valid moves.
|
||||
local row_pos; let "row_pos = $1 % $COLS"
|
||||
|
||||
|
||||
let "move1 = -$kt_skip + $ROWS" # 2 sideways to-the-left, 1 up
|
||||
if [[ `expr $row_pos - $kt_skip` -lt $MIN ]] # An ugly, ugly kludge!
|
||||
then # Can't move off board.
|
||||
move1=$BADMOVE # Not even temporarily.
|
||||
else
|
||||
((valmov++))
|
||||
fi
|
||||
let "move2 = -$kt_hop + $kt_skip * $ROWS" # 1 sideways to-the-left, 2 up
|
||||
if [[ `expr $row_pos - $kt_hop` -lt $MIN ]] # Kludge continued ...
|
||||
then
|
||||
move2=$BADMOVE
|
||||
else
|
||||
((valmov++))
|
||||
fi
|
||||
let "move3 = $kt_hop + $kt_skip * $ROWS" # 1 sideways to-the-right, 2 up
|
||||
if [[ `expr $row_pos + $kt_hop` -ge $COLS ]]
|
||||
then
|
||||
move3=$BADMOVE
|
||||
else
|
||||
((valmov++))
|
||||
fi
|
||||
let "move4 = $kt_skip + $ROWS" # 2 sideways to-the-right, 1 up
|
||||
if [[ `expr $row_pos + $kt_skip` -ge $COLS ]]
|
||||
then
|
||||
move4=$BADMOVE
|
||||
else
|
||||
((valmov++))
|
||||
fi
|
||||
let "move5 = $kt_skip - $ROWS" # 2 sideways to-the-right, 1 dn
|
||||
if [[ `expr $row_pos + $kt_skip` -ge $COLS ]]
|
||||
then
|
||||
move5=$BADMOVE
|
||||
else
|
||||
((valmov++))
|
||||
fi
|
||||
let "move6 = $kt_hop - $kt_skip * $ROWS" # 1 sideways to-the-right, 2 dn
|
||||
if [[ `expr $row_pos + $kt_hop` -ge $COLS ]]
|
||||
then
|
||||
move6=$BADMOVE
|
||||
else
|
||||
((valmov++))
|
||||
fi
|
||||
let "move7 = -$kt_hop - $kt_skip * $ROWS" # 1 sideways to-the-left, 2 dn
|
||||
if [[ `expr $row_pos - $kt_hop` -lt $MIN ]]
|
||||
then
|
||||
move7=$BADMOVE
|
||||
else
|
||||
((valmov++))
|
||||
fi
|
||||
let "move8 = -$kt_skip - $ROWS" # 2 sideways to-the-left, 1 dn
|
||||
if [[ `expr $row_pos - $kt_skip` -lt $MIN ]]
|
||||
then
|
||||
move8=$BADMOVE
|
||||
else
|
||||
((valmov++))
|
||||
fi # There must be a better way to do this.
|
||||
|
||||
local m=( $valmov $move1 $move2 $move3 $move4 $move5 $move6 $move7 $move8 )
|
||||
# ${moves[0]} = number of valid moves.
|
||||
# ${moves[1]} ... ${moves[8]} = possible moves.
|
||||
echo "${m[*]}" # Elements of array to stdout for capture in a var.
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
is_on_board () # Is position actually on the board?
|
||||
{
|
||||
if [[ "$1" -lt "$MIN" || "$1" -gt "$MAX" ]]
|
||||
then
|
||||
return $FAILURE
|
||||
else
|
||||
return $SUCCESS
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
do_move () # Move the knight!
|
||||
{
|
||||
local valid_moves=0
|
||||
local aapos
|
||||
currposl="$1"
|
||||
lmin=$ROWS
|
||||
iex=0
|
||||
squarel=
|
||||
mpm=
|
||||
mov=
|
||||
declare -a p_moves
|
||||
|
||||
########################## DECIDE-MOVE #############################
|
||||
if [ $startpos -ne $CRITPOS ]
|
||||
then # CRITPOS = square #37
|
||||
decide_move
|
||||
else # Needs a special patch for startpos=37 !!!
|
||||
decide_move_patched # Why this particular move and no other ???
|
||||
fi
|
||||
####################################################################
|
||||
|
||||
(( ++movenum )) # Increment move count.
|
||||
let "square = $currposl + ${moves[iex]}"
|
||||
|
||||
################## DEBUG ###############
|
||||
if [ "$DEBUG" ]
|
||||
then debug # Echo debugging information.
|
||||
fi
|
||||
##############################################
|
||||
|
||||
if [[ "$square" -gt $MAX || "$square" -lt $MIN ||
|
||||
${board[square]} -ne $UNVISITED ]]
|
||||
then
|
||||
(( --movenum )) # Decrement move count,
|
||||
echo "RAN OUT OF SQUARES!!!" #+ since previous one was invalid.
|
||||
return $FAIL
|
||||
fi
|
||||
|
||||
board[square]=$movenum
|
||||
currpos=$square # Update current position.
|
||||
((valid_moves++)); # moves[0]=$valid_moves
|
||||
aapos=$(to_algebraic $square)
|
||||
echo -n "$aapos "
|
||||
test $(( $Moves % $LINELEN )) -eq 0 && echo
|
||||
# Print LINELEN=21 moves per line. A valid tour shows 3 complete lines.
|
||||
return $valid_moves # Found a square to move to!
|
||||
}
|
||||
|
||||
|
||||
|
||||
do_move_stupid() # Dingbat algorithm,
|
||||
{ #+ courtesy of script author, *not* Warnsdorff.
|
||||
local valid_moves=0
|
||||
local movloc
|
||||
local squareloc
|
||||
local aapos
|
||||
local cposloc="$1"
|
||||
|
||||
for movloc in {1..8}
|
||||
do # Move to first-found unvisited square.
|
||||
let "squareloc = $cposloc + ${moves[movloc]}"
|
||||
is_on_board $squareloc
|
||||
if [ $? -eq $SUCCESS ] && [ ${board[squareloc]} -eq $UNVISITED ]
|
||||
then # Add conditions to above if-test to improve algorithm.
|
||||
(( ++movenum ))
|
||||
board[squareloc]=$movenum
|
||||
currpos=$squareloc # Update current position.
|
||||
((valid_moves++)); # moves[0]=$valid_moves
|
||||
aapos=$(to_algebraic $squareloc)
|
||||
echo -n "$aapos "
|
||||
test $(( $Moves % $LINELEN )) -eq 0 && echo # Print 21 moves/line.
|
||||
return $valid_moves # Found a square to move to!
|
||||
fi
|
||||
done
|
||||
|
||||
return $FAIL
|
||||
# If no square found in all 8 loop iterations,
|
||||
#+ then Knight's Tour attempt ends in failure.
|
||||
|
||||
# Dingbat algorithm will typically fail after about 30 - 40 moves,
|
||||
#+ but executes _much_ faster than Warnsdorff's in do_move() function.
|
||||
}
|
||||
|
||||
|
||||
|
||||
decide_move () # Which move will we make?
|
||||
{ # But, fails on startpos=37 !!!
|
||||
for mov in {1..8}
|
||||
do
|
||||
let "squarel = $currposl + ${moves[mov]}"
|
||||
is_on_board $squarel
|
||||
if [[ $? -eq $SUCCESS && ${board[squarel]} -eq $UNVISITED ]]
|
||||
then # Find accessible square with least possible future moves.
|
||||
# This is Warnsdorff's algorithm.
|
||||
# What happens is that the knight wanders toward the outer edge
|
||||
#+ of the board, then pretty much spirals inward.
|
||||
# Given two or more possible moves with same value of
|
||||
#+ least-possible-future-moves, this implementation chooses
|
||||
#+ the _first_ of those moves.
|
||||
# This means that there is not necessarily a unique solution
|
||||
#+ for any given starting position.
|
||||
|
||||
possible_moves $squarel
|
||||
mpm=$?
|
||||
p_moves[mov]=$mpm
|
||||
|
||||
if [ $mpm -lt $lmin ] # If less than previous minimum ...
|
||||
then # ^^
|
||||
lmin=$mpm # Update minimum.
|
||||
iex=$mov # Save index.
|
||||
fi
|
||||
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
decide_move_patched () # Decide which move to make,
|
||||
{ # ^^^^^^^ #+ but only if startpos=37 !!!
|
||||
for mov in {1..8}
|
||||
do
|
||||
let "squarel = $currposl + ${moves[mov]}"
|
||||
is_on_board $squarel
|
||||
if [[ $? -eq $SUCCESS && ${board[squarel]} -eq $UNVISITED ]]
|
||||
then
|
||||
possible_moves $squarel
|
||||
mpm=$?
|
||||
p_moves[mov]=$mpm
|
||||
|
||||
if [ $mpm -le $lmin ] # If less-than-or equal to prev. minimum!
|
||||
then # ^^
|
||||
lmin=$mpm
|
||||
iex=$mov
|
||||
fi
|
||||
|
||||
fi
|
||||
done # There has to be a better way to do this.
|
||||
}
|
||||
|
||||
|
||||
|
||||
possible_moves () # Calculate number of possible moves,
|
||||
{ #+ given the current position.
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
return $FAIL
|
||||
fi
|
||||
|
||||
local curr_pos=$1
|
||||
local valid_movl=0
|
||||
local icx=0
|
||||
local movl
|
||||
local sq
|
||||
declare -a movesloc
|
||||
|
||||
movesloc=( $(generate_moves $curr_pos) )
|
||||
|
||||
for movl in {1..8}
|
||||
do
|
||||
let "sq = $curr_pos + ${movesloc[movl]}"
|
||||
is_on_board $sq
|
||||
if [ $? -eq $SUCCESS ] && [ ${board[sq]} -eq $UNVISITED ]
|
||||
then
|
||||
((valid_movl++));
|
||||
fi
|
||||
done
|
||||
|
||||
return $valid_movl # Found a square to move to!
|
||||
}
|
||||
|
||||
|
||||
strategy ()
|
||||
{
|
||||
echo
|
||||
|
||||
if [ -n "$STUPID" ]
|
||||
then
|
||||
for Moves in {1..63}
|
||||
do
|
||||
cposl=$1
|
||||
moves=( $(generate_moves $currpos) )
|
||||
do_move_stupid "$currpos"
|
||||
if [ $? -eq $FAIL ]
|
||||
then
|
||||
failure
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Don't need an "else" clause here,
|
||||
#+ because Stupid Strategy will always fail and exit!
|
||||
for Moves in {1..63}
|
||||
do
|
||||
cposl=$1
|
||||
moves=( $(generate_moves $currpos) )
|
||||
do_move "$currpos"
|
||||
if [ $? -eq $FAIL ]
|
||||
then
|
||||
failure
|
||||
fi
|
||||
|
||||
done
|
||||
# Could have condensed above two do-loops into a single one,
|
||||
echo #+ but this would have slowed execution.
|
||||
|
||||
print_board
|
||||
echo
|
||||
echo "Knight's Tour ends on $(to_algebraic $currpos) [square #$currpos]."
|
||||
return $SUCCESS
|
||||
}
|
||||
|
||||
debug ()
|
||||
{ # Enable this by setting DEBUG=1 near beginning of script.
|
||||
local n
|
||||
|
||||
echo "================================="
|
||||
echo " At move number $movenum:"
|
||||
echo " *** possible moves = $mpm ***"
|
||||
# echo "### square = $square ###"
|
||||
echo "lmin = $lmin"
|
||||
echo "${moves[@]}"
|
||||
|
||||
for n in {1..8}
|
||||
do
|
||||
echo -n "($n):${p_moves[n]} "
|
||||
done
|
||||
|
||||
echo
|
||||
echo "iex = $iex :: moves[iex] = ${moves[iex]}"
|
||||
echo "square = $square"
|
||||
echo "================================="
|
||||
echo
|
||||
} # Gives pretty complete status after ea. move.
|
||||
|
||||
|
||||
|
||||
# =============================================================== #
|
||||
# int main () {
|
||||
from_algebraic "$1"
|
||||
startpos=$?
|
||||
if [ "$startpos" -eq "$FAIL" ] # Okay even if no $1.
|
||||
then # ^^^^^^^^^^^ Okay even if input -lt 0.
|
||||
echo "No starting square specified (or illegal input)."
|
||||
let "startpos = $RANDOM % $SQUARES" # 0 - 63 permissable range.
|
||||
fi
|
||||
|
||||
|
||||
if [ "$2" = "stupid" ]
|
||||
then
|
||||
STUPID=1
|
||||
echo -n " ### Stupid Strategy ###"
|
||||
else
|
||||
STUPID=''
|
||||
echo -n " *** Warnsdorff's Algorithm ***"
|
||||
fi
|
||||
|
||||
|
||||
initialize_board
|
||||
|
||||
movenum=0
|
||||
board[startpos]=$movenum # Mark each board square with move number.
|
||||
currpos=$startpos
|
||||
algpos=$(to_algebraic $startpos)
|
||||
|
||||
echo; echo "Starting from $algpos [square #$startpos] ..."; echo
|
||||
echo -n "Moves:"
|
||||
|
||||
strategy "$currpos"
|
||||
|
||||
echo
|
||||
|
||||
exit 0 # return 0;
|
||||
|
||||
# } # End of main() pseudo-function.
|
||||
# =============================================================== #
|
||||
|
||||
|
||||
# Exercises:
|
||||
# ---------
|
||||
#
|
||||
# 1) Extend this example to a 10 x 10 board or larger.
|
||||
# 2) Improve the "stupid strategy" by modifying the
|
||||
# do_move_stupid function.
|
||||
# Hint: Prevent straying into corner squares in early moves
|
||||
# (the exact opposite of Warnsdorff's algorithm!).
|
||||
# 3) This script could stand considerable improvement and
|
||||
# streamlining, especially in the poorly-written
|
||||
# generate_moves() function
|
||||
# and in the DECIDE-MOVE patch in the do_move() function.
|
||||
# Must figure out why standard algorithm fails for startpos=37 ...
|
||||
#+ but _not_ on any other, including symmetrical startpos=26.
|
||||
# Possibly, when calculating possible moves, counts the move back
|
||||
#+ to the originating square. If so, it might be a relatively easy fix.
|
|
@ -42,7 +42,7 @@ fi
|
|||
#+ and
|
||||
#+ default file "gen0" not present.
|
||||
|
||||
E_NOSTARTFILE=68
|
||||
E_NOSTARTFILE=86
|
||||
|
||||
if [ ! -e "$startfile" ]
|
||||
then
|
||||
|
@ -65,7 +65,7 @@ COLS=10
|
|||
# ---------------------------------------------------------- #
|
||||
|
||||
GENERATIONS=10 # How many generations to cycle through.
|
||||
# Adjust this upwards,
|
||||
# Adjust this upwards
|
||||
#+ if you have time on your hands.
|
||||
|
||||
NONE_ALIVE=85 # Exit status on premature bailout,
|
||||
|
@ -120,7 +120,7 @@ do
|
|||
fi
|
||||
|
||||
echo -n "$cell" | sed -e 's/_/ /g'
|
||||
# Print out array and change underscores to spaces.
|
||||
# Print out array, changing underscores to spaces.
|
||||
done
|
||||
|
||||
return
|
||||
|
@ -164,7 +164,7 @@ return $TRUE # Valid coordinate.
|
|||
|
||||
|
||||
IsAlive () # Test whether cell is alive.
|
||||
# Takes array, cell number,
|
||||
# Takes array, cell number, and
|
||||
{ #+ state of cell as arguments.
|
||||
GetCount "$1" $2 # Get alive cell count in neighborhood.
|
||||
local nhbd=$?
|
||||
|
@ -179,7 +179,7 @@ IsAlive () # Test whether cell is alive.
|
|||
return $ALIVE
|
||||
fi
|
||||
|
||||
return $DEAD # Dead by default.
|
||||
return $DEAD # Dead, by default.
|
||||
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ GetCount () # Count live cells in passed cell's neighborhood.
|
|||
if [ $? -eq "$TRUE" ]
|
||||
then
|
||||
if [ ${array[$t_cen]} = "$ALIVE1" ] # Is it alive?
|
||||
then # Yes?
|
||||
then # If yes, then ...
|
||||
let "count += 1" # Increment count.
|
||||
fi
|
||||
fi
|
||||
|
@ -294,7 +294,7 @@ echo "Generation $generation - $alive alive"
|
|||
if [ "$alive" -eq 0 ]
|
||||
then
|
||||
echo
|
||||
echo "Unexpected exit: no more cells alive!"
|
||||
echo "Premature exit: no more cells alive!"
|
||||
exit $NONE_ALIVE # No point in continuing
|
||||
fi #+ if no live cells.
|
||||
|
||||
|
@ -307,8 +307,8 @@ fi #+ if no live cells.
|
|||
|
||||
# Load initial array with contents of startup file.
|
||||
initial=( `cat "$startfile" | sed -e '/#/d' | tr -d '\n' |\
|
||||
sed -e 's/\./\. /g' -e 's/_/_ /g'` )
|
||||
# Delete lines containing '#' comment character.
|
||||
sed -e 's/\./\. /g' -e 's/_/_ /g'` )
|
||||
# Remove linefeeds and insert space between elements.
|
||||
|
||||
clear # Clear screen.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# A rudimentary man page editor
|
||||
|
||||
# Version: 0.1 (Alpha, probably buggy)
|
||||
# Author: Mendel Cooper <thegrendel@theriver.com>
|
||||
# Author: Mendel Cooper <thegrendel.abs@gmail.com>
|
||||
# Reldate: 16 June 2008
|
||||
# License: GPL3
|
||||
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
#!/bin/bash
|
||||
# msquare.sh
|
||||
# Magic Square generator (odd-order squares only!)
|
||||
|
||||
# Author: mendel cooper
|
||||
# reldate: 19 Jan. 2009
|
||||
# License: Public Domain
|
||||
# A C-program by Kwon Young Shin inspired this script.
|
||||
# See http://user.chollian.net/~brainstm/MagicSquare.htm ...
|
||||
|
||||
# Definition: A "magic square" is a two-dimensional array
|
||||
# of integers in which all the rows, columns,
|
||||
# and *long* diagonals add up to the same number.
|
||||
# Being "square," the array has the same number
|
||||
# of rows and columns.
|
||||
# An example of a magic square of order 3 is:
|
||||
# 8 1 6
|
||||
# 3 5 7
|
||||
# 4 9 2
|
||||
# All the rows, columns, and long diagonals add up to 15.
|
||||
|
||||
|
||||
# Globals
|
||||
EVEN=2
|
||||
MAXSIZE=31 # 31 rows x 31 cols.
|
||||
E_usage=90 # Invocation error.
|
||||
dimension=
|
||||
declare -i square
|
||||
|
||||
usage_message ()
|
||||
{
|
||||
echo "Usage: $0 square-size"
|
||||
echo " ... where \"square-size\" is an ODD integer"
|
||||
echo " in the range 3 - 31."
|
||||
# Actually works for squares up to order 159,
|
||||
#+ but large squares will not display pretty-printed in a term window.
|
||||
# Try increasing MAXSIZE, above.
|
||||
exit $E_usage
|
||||
}
|
||||
|
||||
|
||||
calculate () # Here's where the actual work gets done.
|
||||
{
|
||||
local row col index dimadj j k cell_val=1
|
||||
dimension=$1
|
||||
|
||||
let "dimadj = $dimension * 3"; let "dimadj /= 2" # x 1.5, then truncate.
|
||||
|
||||
for ((j=0; j < dimension; j++))
|
||||
do
|
||||
for ((k=0; k < dimension; k++))
|
||||
do # Calculate indices, then convert to 1-dim. array index.
|
||||
# Bash doesn't support multidimensional arrays. Pity.
|
||||
let "col = $k - $j + $dimadj"; let "col %= $dimension"
|
||||
let "row = $j * 2 - $k + $dimension"; let "row %= $dimension"
|
||||
let "index = $row*($dimension) + $col"
|
||||
square[$index]=cell_val; ((cell_val++))
|
||||
done
|
||||
done
|
||||
} # Plain math, no visualization required.
|
||||
|
||||
|
||||
print_square () # Output square, one row at a time.
|
||||
{
|
||||
local row col idx d1
|
||||
let "d1 = $dimension - 1" # Adjust for zero-indexed array.
|
||||
|
||||
for row in $(seq 0 $d1)
|
||||
do
|
||||
|
||||
for col in $(seq 0 $d1)
|
||||
do
|
||||
let "idx = $row * $dimension + $col"
|
||||
printf "%3d " "${square[idx]}"; echo -n " "
|
||||
done # Displays up to 13-order neatly in 80-column term window.
|
||||
|
||||
echo # Newline after each row.
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
#################################################
|
||||
if [[ -z "$1" ]] || [[ "$1" -gt $MAXSIZE ]]
|
||||
then
|
||||
usage_message
|
||||
fi
|
||||
|
||||
let "test_even = $1 % $EVEN"
|
||||
if [ $test_even -eq 0 ]
|
||||
then # Can't handle even-order squares.
|
||||
usage_message
|
||||
fi
|
||||
|
||||
calculate $1
|
||||
print_square # echo "${square[@]}" # DEBUG
|
||||
|
||||
exit $?
|
||||
#################################################
|
||||
|
||||
|
||||
# Exercises:
|
||||
# ---------
|
||||
# 1) Add a function to calculate the sum of each row, column,
|
||||
# and *long* diagonal. The sums must match.
|
||||
# This is the "magic constant" of that particular order square.
|
||||
# 2) Have the print_square function auto-calculate how much space
|
||||
# to allot between square elements for optimized display.
|
||||
# This might require parameterizing the "printf" line.
|
||||
# 3) Add appropriate functions for generating magic squares
|
||||
# with an *even* number of rows/columns.
|
||||
# This is non-trivial(!).
|
||||
# See the URL for Kwon Young Shin, above, for help.
|
|
@ -15,13 +15,11 @@ volume=$'\xc0' # Max volume = \xff (or \x00).
|
|||
mute=$'\x80' # No volume = \x80 (the middle).
|
||||
|
||||
function mknote () # $1=Note Hz in bytes (e.g. A = 440Hz ::
|
||||
#+ 8000 fps / 440 = 16 :: A = 16 bytes per second)
|
||||
{
|
||||
{ #+ 8000 fps / 440 = 16 :: A = 16 bytes per second)
|
||||
for t in `seq 0 $duration`
|
||||
do
|
||||
test $(( $t % $1 )) = 0 && echo -n $volume || echo -n $mute
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
e=`mknote 49`
|
||||
|
@ -39,4 +37,4 @@ echo -n "$g$e2$d$c$d$c$a$g$n$g$e$n$g$e2$d$c$c$b$c$cis$n$cis$d \
|
|||
$n$g$e2$d$c$d$c$a$g$n$g$e$n$g$a$d$c$b$a$b$c" > /dev/dsp
|
||||
# dsp = Digital Signal Processor
|
||||
|
||||
exit $? # A "bonny" example of a shell script!
|
||||
exit # A "bonny" example of a shell script!
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#!/bin/bash
|
||||
# pad.sh
|
||||
|
||||
######################################################
|
||||
#######################################################
|
||||
# PAD (xml) file creator
|
||||
#+ Written by Mendel Cooper <thegrendel@theriver.com>.
|
||||
#+ Written by Mendel Cooper <thegrendel.abs@gmail.com>.
|
||||
#+ Released to the Public Domain.
|
||||
#
|
||||
# Generates a "PAD" descriptor file for shareware
|
||||
#+ packages, according to the specifications
|
||||
#+ of the ASP.
|
||||
# http://www.asp-shareware.org/pad
|
||||
######################################################
|
||||
#######################################################
|
||||
|
||||
|
||||
# Accepts (optional) save filename as a command-line argument.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
# poem.sh: Pretty-prints one of the document author's favorite poems.
|
||||
# poem.sh: Pretty-prints one of the ABS Guide author's favorite poems.
|
||||
|
||||
# Lines of the poem (single stanza).
|
||||
Line[1]="I do not know which to prefer,"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
##############################################################
|
||||
# QUACKEY: a somewhat simplified version of Perquackey [TM]. #
|
||||
# #
|
||||
# Author: Mendel Cooper <thegrendel@theriver.com> #
|
||||
# Author: Mendel Cooper <thegrendel.abs@gmail.com> #
|
||||
# version 0.1.02 03 May, 2008 #
|
||||
# License: GPL3 #
|
||||
##############################################################
|
||||
|
@ -13,9 +13,9 @@ WLIST=/usr/share/dict/word.lst
|
|||
# ^^^^^^^^ Word list file found here.
|
||||
# ASCII word list, one word per line, UNIX format.
|
||||
# A suggested list is the script author's "yawl" word list package.
|
||||
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
|
||||
# http://bash.neuralshortciruit.com/yawl-0.3.2.tar.gz
|
||||
# or
|
||||
# http://personal.riverusers.com/~thegrendel/yawl-0.3.2.tar.gz
|
||||
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
|
||||
|
||||
NONCONS=0 # Word not constructable from letter set.
|
||||
CONS=1 # Constructable.
|
||||
|
@ -462,4 +462,4 @@ exit $?
|
|||
# 7) Fix bugs!!!
|
||||
|
||||
# Reference for more info:
|
||||
# http://personal.riverusers.com/~thegrendel/qky.README.html
|
||||
# http://bash.neuralshortcircuit.com/qky.README.html
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# quote-fetch.sh: Download a stock quote.
|
||||
|
||||
|
||||
E_NOPARAMS=66
|
||||
E_NOPARAMS=86
|
||||
|
||||
if [ -z "$1" ] # Must specify a stock (symbol) to fetch.
|
||||
then echo "Usage: `basename $0` stock-symbol"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# rand-string.sh
|
||||
# Generating an 8-character "random" string.
|
||||
|
||||
if [ "-n $1" ] # If command-line argument present,
|
||||
if [ -n "$1" ] # If command-line argument present,
|
||||
then #+ then set start-string to it.
|
||||
str0="$1"
|
||||
else # Else use PID of script as start-string.
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
# Soundex script
|
||||
# by
|
||||
# Mendel Cooper
|
||||
# thegrendel@theriver.com
|
||||
# 23 January, 2002
|
||||
# thegrendel.abs@gmail.com
|
||||
# reldate: 23 January, 2002
|
||||
#
|
||||
# Placed in the Public Domain.
|
||||
#
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
|
||||
ARGCOUNT=1 # Need name as argument.
|
||||
E_WRONGARGS=70
|
||||
E_WRONGARGS=90
|
||||
|
||||
if [ $# -ne "$ARGCOUNT" ]
|
||||
then
|
||||
|
@ -82,9 +82,9 @@ let "char_pos += 1" # Bump character position to 2nd letter of name.
|
|||
name1=${name:$char_pos}
|
||||
|
||||
|
||||
# ++++++++++++++++++++++++++ Exception Patch +++++++++++++++++++++++++++++++++
|
||||
# Now, we run both the input name and the name shifted one char to the right
|
||||
#+ through the value-assigning function.
|
||||
# ++++++++++++++++++++++++++ Exception Patch ++++++++++++++++++++++++++++++
|
||||
# Now, we run both the input name and the name shifted one char
|
||||
#+ to the right through the value-assigning function.
|
||||
# If we get the same value out, that means that the first two characters
|
||||
#+ of the name have the same value assigned, and that one should cancel.
|
||||
# However, we also need to test whether the first letter of the name
|
||||
|
@ -111,7 +111,7 @@ then
|
|||
else
|
||||
suffix=${s2:$char_pos}
|
||||
fi
|
||||
# ++++++++++++++++++++++ end Exception Patch +++++++++++++++++++++++++++++++++
|
||||
# ++++++++++++++++++++++ end Exception Patch ++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
padding=000 # Use at most 3 zeroes to pad.
|
||||
|
|
|
@ -23,7 +23,7 @@ IMGDIR="images" # Image directory
|
|||
# Headers
|
||||
HDR01='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'
|
||||
HDR02='<!-- Converted to HTML by ***tohtml.sh*** script -->'
|
||||
HDR03='<!-- script author: M. Leo Cooper <thegrendel@theriver.com> -->'
|
||||
HDR03='<!-- script author: M. Leo Cooper <thegrendel.abs@gmail.com> -->'
|
||||
HDR10='<html>'
|
||||
HDR11='<head>'
|
||||
HDR11a='</head>'
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
# ===========================================================
|
||||
# Standard Check for Script Argument(s)
|
||||
ARGS=1
|
||||
E_BADARGS=65
|
||||
E_NOFILE=66
|
||||
E_BADARGS=85
|
||||
E_NOFILE=86
|
||||
|
||||
if [ $# -ne $ARGS ]
|
||||
then
|
||||
|
@ -31,7 +31,7 @@ WORDFILE=/usr/share/dict/linux.words # Dictionary file.
|
|||
# May specify a different word list file
|
||||
#+ of one-word-per-line format.
|
||||
# For example, the "yawl" word-list package,
|
||||
# http://personal.riverusers.com/~thegrendel/yawl-0.3.2.tar.gz
|
||||
# http://bash.neuralshortcircuit.com/yawl-0.3.2.tar.gz
|
||||
|
||||
|
||||
wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \
|
||||
|
|
Loading…
Reference in New Issue