This commit is contained in:
gferg 2009-01-22 14:43:09 +00:00
parent 54b9f39293
commit dc5f74fc57
26 changed files with 1584 additions and 518 deletions

View File

@ -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!)

View File

@ -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>

View File

@ -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)

View File

@ -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
<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,10 +1889,10 @@ 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>
<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>
@ -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 &lt;Ctl-V&gt;&lt;Ctl-J&gt;</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 &lt;Ctl-V&gt;&lt;Ctl-J&gt;</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,9 +3763,10 @@ 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>
<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>
@ -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>
@ -8569,6 +8592,21 @@ echo ${stringZ/abc/xyz} # xyzABC123ABCabc
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
@ -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>
@ -22859,9 +22909,11 @@ mount -o loop /dev/loop0 /mnt # Mount it.
<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&reg; 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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -1,41 +1,47 @@
#===============================================================
#=============================================================
#
# PERSONAL $HOME/.bashrc FILE for bash-2.05a (or later)
#
# Last modified: Tue Apr 15 20:32:34 CEST 2003
# PERSONAL $HOME/.bashrc FILE for bash-3.0 (or later)
# By Emmanuel Rouat &lt;no-email&gt;
#
# Last modified: Sun Nov 30 16:27:45 CET 2008
# This file is read (normally) by interactive shells only.
# Here is the place to define your aliases, functions and
# other interactive features like your prompt.
#
# This file was designed (originally) for Solaris but based
# on Redhat's default .bashrc file
# --> Modified for Linux.
# The majority of the code you'll find here is based on code found
# on Usenet (or internet).
# This bashrc file is a bit overcrowded - remember it is just
# just an example. Tailor it to your needs
# The majority of the code here assumes you are on a GNU
# system (most likely a Linux box) and is based on code found
# on Usenet or internet. See for instance:
#
# http://tldp.org/LDP/abs/html/index.html
# http://www.caliban.org/bash/
# http://www.shelldorado.com/scripts/categories.html
# http://www.dotfiles.org/
#
# This bashrc file is a bit overcrowded -- remember it is just
# just an example. Tailor it to your needs.
#
#
#===============================================================
#=============================================================
# --> Comments added by HOWTO author.
# --> And then edited again by ER :-)
#-----------------------------------
#-------------------------------------------------------------
# Source global definitions (if any)
#-----------------------------------
#-------------------------------------------------------------
if [ -f /etc/bashrc ]; then
. /etc/bashrc # --> Read /etc/bashrc, if present.
fi
#-------------------------------------------------------------
# Automatic setting of $DISPLAY (if not set already)
# This works for linux - your mileage may vary....
# Automatic setting of $DISPLAY (if not set already).
# This works for linux - your mileage may vary. ...
# The problem is that different types of terminals give
# different answers to 'who am i'......
# I have not found a 'universal' method yet
# different answers to 'who am i' (rxvt in particular can be
# troublesome).
# I have not found a 'universal' method yet.
#-------------------------------------------------------------
function get_xserver ()
@ -51,60 +57,60 @@ function get_xserver ()
XSERVER=${XSERVER%%:*}
;;
aterm | rxvt)
# find some code that works here.....
# Find some code that works here. ...
;;
esac
}
if [ -z ${DISPLAY:=""} ]; then
get_xserver
if [[ -z ${XSERVER} || ${XSERVER} == $(hostname) ||
if [[ -z ${XSERVER} || ${XSERVER} == $(hostname) || \
${XSERVER} == "unix" ]]; then
DISPLAY=":0.0" # Display on local host
DISPLAY=":0.0" # Display on local host.
else
DISPLAY=${XSERVER}:0.0 # Display on remote host
DISPLAY=${XSERVER}:0.0 # Display on remote host.
fi
fi
export DISPLAY
#---------------
#-------------------------------------------------------------
# Some settings
#---------------
#-------------------------------------------------------------
ulimit -S -c 0 # Don't want any coredumps
ulimit -S -c 0 # Don't want any coredumps.
set -o notify
set -o noclobber
set -o ignoreeof
set -o nounset
#set -o xtrace # Useful for debuging
#set -o xtrace # Useful for debuging.
# Enable options:
shopt -s cdspell
shopt -s cdable_vars
shopt -s checkhash
shopt -s checkwinsize
shopt -s mailwarn
shopt -s sourcepath
shopt -s no_empty_cmd_completion # bash>=2.04 only
shopt -s no_empty_cmd_completion
shopt -s cmdhist
shopt -s histappend histreedit histverify
shopt -s extglob # Necessary for programmable completion
shopt -s extglob # Necessary for programmable completion.
# Disable options:
shopt -u mailwarn
unset MAILCHECK # I don't want my shell to warn me of incoming mail
unset MAILCHECK # Don't want my shell to warn me of incoming mail.
export TIMEFORMAT=$'\nreal %3R\tuser %3U\tsys %3S\tpcpu %P\n'
export HISTTIMEFORMAT="%H:%M > "
export HISTIGNORE="&:bg:fg:ll:h"
export HOSTFILE=$HOME/.hosts # Put a list of remote hosts in ~/.hosts
export HOSTFILE=$HOME/.hosts # Put list of remote hosts in ~/.hosts ...
#-----------------------
#-------------------------------------------------------------
# Greeting, motd etc...
#-----------------------
#-------------------------------------------------------------
# Define some colors first:
red='\e[0;31m'
@ -116,25 +122,28 @@ CYAN='\e[1;36m'
NC='\e[0m' # No Color
# --> Nice. Has the same effect as using "ansi.sys" in DOS.
# Looks best on a black background.....
# Looks best on a terminal with black background.....
echo -e "${CYAN}This is BASH ${RED}${BASH_VERSION%.*}\
${CYAN} - DISPLAY on ${RED}$DISPLAY${NC}\n"
date
if [ -x /usr/games/fortune ]; then
/usr/games/fortune -s # makes our day a bit more fun.... :-)
/usr/games/fortune -s # Makes our day a bit more fun.... :-)
fi
function _exit() # function to run upon exit of shell
function _exit() # Function to run upon exit of shell.
{
echo -e "${RED}Hasta la vista, baby${NC}"
}
trap _exit EXIT
#---------------
# Shell Prompt
#---------------
if [[ "${DISPLAY#$HOST}" != ":0.0" && "${DISPLAY}" != ":0" ]]; then
#-------------------------------------------------------------
# Shell Prompt
#-------------------------------------------------------------
if [[ "${DISPLAY%%:0*}" != "" ]]; then
HILIT=${red} # remote machine: prompt will be partly red
else
HILIT=${cyan} # local machine: prompt will be partly cyan
@ -156,36 +165,37 @@ function fastprompt()
esac
}
_powerprompt()
{
LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g")
}
function powerprompt()
{
_powerprompt()
{
LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g")
}
PROMPT_COMMAND=_powerprompt
case $TERM in
*term | rxvt )
PS1="${HILIT}[\A \$LOAD]$NC\n[\h \#] \W > \
PS1="${HILIT}[\A - \$LOAD]$NC\n[\u@\h \#] \W > \
\[\033]0;\${TERM} [\u@\h] \w\007\]" ;;
linux )
PS1="${HILIT}[\A - \$LOAD]$NC\n[\h \#] \w > " ;;
PS1="${HILIT}[\A - \$LOAD]$NC\n[\u@\h \#] \W > " ;;
* )
PS1="[\A - \$LOAD]\n[\h \#] \w > " ;;
PS1="[\A - \$LOAD]\n[\u@\h \#] \W > " ;;
esac
}
powerprompt # This is the default prompt -- might be slow.
# If too slow, use fastprompt instead.
# If too slow, use fastprompt instead. ...
#===============================================================
#
# ALIASES AND FUNCTIONS
#
# Arguably, some functions defined here are quite big
# (ie 'lowercase') but my workstation has 512Meg of RAM, so ...
# Arguably, some functions defined here are quite big.
# If you want to make this file smaller, these functions can
# be converted into scripts.
# be converted into scripts and removed from here.
#
# Many functions were taken (almost) straight from the bash-2.04
# examples.
@ -204,52 +214,68 @@ alias mkdir='mkdir -p'
alias h='history'
alias j='jobs -l'
alias r='rlogin'
alias which='type -all'
alias which='type -a'
alias ..='cd ..'
alias path='echo -e ${PATH//:/\\n}'
alias libpath='echo -e ${LD_LIBRARY_PATH//:/\\n}'
alias print='/usr/bin/lp -o nobanner -d $LPDEST'
# Assumes LPDEST is defined
# Assumes LPDEST is defined (default printer)
alias pjet='enscript -h -G -fCourier9 -d $LPDEST'
# Pretty-print using enscript
alias background='xv -root -quit -max -rmode 5'
# Put a picture in the background
alias du='du -kh'
alias du='du -kh' # Makes a more readable output.
alias df='df -kTh'
# The 'ls' family (this assumes you use the GNU ls)
alias la='ls -Al' # show hidden files
#-------------------------------------------------------------
# The 'ls' family (this assumes you use a recent GNU ls)
#-------------------------------------------------------------
alias ll="ls -l --group-directories-first"
alias ls='ls -hF --color' # add colors for filetype recognition
alias la='ls -Al' # show hidden files
alias lx='ls -lXB' # sort by extension
alias lk='ls -lSr' # sort by size
alias lc='ls -lcr' # sort by change time
alias lu='ls -lur' # sort by access time
alias lr='ls -lR' # recursive ls
alias lt='ls -ltr' # sort by date
alias lk='ls -lSr' # sort by size, biggest last
alias lc='ls -ltcr' # sort by and show change time, most recent last
alias lu='ls -ltur' # sort by and show access time, most recent last
alias lt='ls -ltr' # sort by date, most recent last
alias lm='ls -al |more' # pipe through 'more'
alias tree='tree -Csu' # nice alternative to 'ls'
alias lr='ls -lR' # recursive ls
alias tree='tree -Csu' # nice alternative to 'recursive ls'
# If your version of 'ls' doesn't support --group-directories-first try this:
# function ll(){ ls -l "$@"| egrep "^d" ; ls -lXB "$@" 2>&-| \
# egrep -v "^d|total "; }
#-------------------------------------------------------------
# tailoring 'less'
#-------------------------------------------------------------
alias more='less'
export PAGER=less
export LESSCHARSET='latin1'
export LESSOPEN='|/usr/bin/lesspipe.sh %s 2>&-'
# Use this if lesspipe.sh exists.
# Use this if lesspipe.sh exists
export LESS='-i -N -w -z-4 -g -e -M -X -F -R -P%t?f%f \
:stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...'
# spelling typos - highly personnal :-)
#-------------------------------------------------------------
# spelling typos - highly personnal and keyboard-dependent :-)
#-------------------------------------------------------------
alias xs='cd'
alias vf='cd'
alias moer='more'
alias moew='more'
alias kk='ll'
#----------------
# a few fun ones
#----------------
function xtitle ()
#-------------------------------------------------------------
# A few fun ones
#-------------------------------------------------------------
function xtitle() # Adds some text in the terminal frame.
{
case "$TERM" in
*term | rxvt)
@ -259,13 +285,13 @@ function xtitle ()
esac
}
# aliases...
# aliases that use xtitle
alias top='xtitle Processes on $HOST && top'
alias make='xtitle Making $(basename $PWD) ; make'
alias ncftp="xtitle ncFTP ; ncftp"
# .. and functions
function man ()
function man()
{
for i ; do
xtitle The $(basename $1|tr -d .[:digit:]) manual
@ -273,10 +299,12 @@ function man ()
done
}
function ll()
{ ls -l "$@"| egrep "^d" ; ls -lXB "$@" 2>&-| egrep -v "^d|total "; }
function te() # wrapper around xemacs/gnuserv
#-------------------------------------------------------------
# Make the following commands run in background automatically:
#-------------------------------------------------------------
function te() # Wrapper around xemacs/gnuserv ...
{
if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then
gnuclient -q "$@";
@ -285,20 +313,25 @@ function te() # wrapper around xemacs/gnuserv
fi
}
#-----------------------------------
# File & strings related functions:
#-----------------------------------
function soffice() { command soffice "$@" & }
function firefox() { command firefox "$@" & }
function xpdf() { command xpdf "$@" & }
#-------------------------------------------------------------
# File & string-related functions:
#-------------------------------------------------------------
# Find a file with a pattern in name:
function ff()
function ff() { find . -type f -iname '*'$*'*' -ls ; }
{ find . -type f -iname '*'$*'*' -ls ; }
# Find a file with pattern $1 in name and Execute $2 on it:
function fe()
{ find . -type f -iname '*'$1'*' -exec "${2:-file}" {} \; ; }
# find pattern in a set of filesand highlight them:
{ find . -type f -iname '*'${1:-}'*' -exec ${2:-file} {} \; ; }
# Find a pattern in a set of files and highlight them:
# (needs a recent version of egrep)
function fstr()
{
OPTIND=1
@ -317,14 +350,12 @@ Usage: fstr [-i] \"pattern\" [\"filename pattern\"] "
echo "$usage"
return;
fi
local SMSO=$(tput smso)
local RMSO=$(tput rmso)
find . -type f -name "${2:-*}" -print0 |
xargs -0 grep -sn ${case} "$1" 2>&- | \
sed "s/$1/${SMSO}\0${RMSO}/gI" | more
find . -type f -name "${2:-*}" -print0 | \
xargs -0 egrep --color=always -sn ${case} "$1" 2>&- | more
}
function cuttail() # Cut last n lines in file, 10 by default.
function cuttail() # cut last n lines in file, 10 by default
{
nlines=${2:-10}
sed -n -e :a -e "1,${nlines}!{P;N;D;};N;ba" $1
@ -349,30 +380,54 @@ function lowercase() # move filenames to lowercase
done
}
function swap() # swap 2 filenames around
{
function swap() # Swap 2 filenames around, if they exist
{ #(from Uzi's bashrc).
local TMPFILE=tmp.$$
[ $# -ne 2 ] && echo "swap: 2 arguments needed" && return 1
[ ! -e $1 ] && echo "swap: $1 does not exist" && return 1
[ ! -e $2 ] && echo "swap: $2 does not exist" && return 1
mv "$1" $TMPFILE
mv "$2" "$1"
mv $TMPFILE "$2"
}
#-----------------------------------
# Process/system related functions:
#-----------------------------------
function my_ps()
{ ps $@ -u $USER -o pid,%cpu,%mem,bsdtime,command ; }
function pp()
{ my_ps f | awk '!/awk/ && $0~var' var=${1:-".*"} ; }
# This function is roughly the same as 'killall' on linux
# but has no equivalent (that I know of) on Solaris
function killps() # kill by process name
function extract() # Handy Extract Program.
{
local pid pname sig="-TERM" # default signal
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xvjf $1 ;;
*.tar.gz) tar xvzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) unrar x $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xvf $1 ;;
*.tbz2) tar xvjf $1 ;;
*.tgz) tar xvzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "'$1' cannot be extracted via >extract<" ;;
esac
else
echo "'$1' is not a valid file"
fi
}
#-------------------------------------------------------------
# Process/system related functions:
#-------------------------------------------------------------
function my_ps() { ps $@ -u $USER -o pid,%cpu,%mem,bsdtime,command ; }
function pp() { my_ps f | awk '!/awk/ && $0~var' var=${1:-".*"} ; }
function killps() # Kill by process name.
{
local pid pname sig="-TERM" # Default signal.
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
echo "Usage: killps [-SIGNAL] pattern"
return;
@ -386,7 +441,7 @@ function killps() # kill by process name
done
}
function my_ip() # get IP adresses
function my_ip() # Get IP adresses.
{
MY_IP=$(/sbin/ifconfig ppp0 | awk '/inet/ { print $2 } ' | \
sed -e s/addr://)
@ -394,7 +449,7 @@ sed -e s/addr://)
sed -e s/P-t-P://)
}
function ii() # get current host related info
function ii() # Get current host related info.
{
echo -e "\nYou are logged on ${RED}$HOST"
echo -e "\nAdditionnal information:$NC " ; uname -a
@ -405,12 +460,15 @@ function ii() # get current host related info
my_ip 2>&- ;
echo -e "\n${RED}Local IP Address :$NC" ; echo ${MY_IP:-"Not connected"}
echo -e "\n${RED}ISP Address :$NC" ; echo ${MY_ISP:-"Not connected"}
echo -e "\n${RED}Open connections :$NC "; netstat -pan --inet;
echo
}
#-------------------------------------------------------------
# Misc utilities:
#-------------------------------------------------------------
function repeat() # repeat n times command
function repeat() # Repeat n times command.
{
local i max
max=$1; shift;
@ -419,7 +477,8 @@ function repeat() # repeat n times command
done
}
function ask()
function ask() # See 'killps' for example of use.
{
echo -n "$@" '[y/n] ' ; read ans
case "$ans" in
@ -428,24 +487,31 @@ function ask()
esac
}
#=======================================================================
#
# PROGRAMMABLE COMPLETION - ONLY SINCE BASH-2.04
# Most are taken from the bash 2.05 documentation and from Ian McDonalds
# 'Bash completion' package
# (http://www.caliban.org/bash/index.shtml#completion)
# You will in fact need bash-2.05a for some features
#
#=======================================================================
function corename() # Get name of app that created a corefile.
{
for file ; do
echo -n $file : ; gdb --core=$file --batch | head -1
done
}
if [ "${BASH_VERSION%.*}" \< "2.05" ]; then
echo "You will need to upgrade to version 2.05 \
for programmable completion"
#=========================================================================
# PROGRAMMABLE COMPLETION - ONLY SINCE BASH-2.04
# Most are taken from the bash 2.05 documentation and from Ian McDonald's
# 'Bash completion' package (http://www.caliban.org/bash/#completion).
# You will in fact need bash more recent than 3.0 for some features.
#=========================================================================
if [ "${BASH_VERSION%.*}" \< "3.0" ]; then
echo "You will need to upgrade to version 3.0 \
for full programmable completion features."
return
fi
shopt -s extglob # necessary
set +o nounset # otherwise some completions will fail
shopt -s extglob # Necessary,
#set +o nounset # otherwise some completions will fail.
complete -A hostname rsh rcp telnet rlogin r ftp ping disk
complete -A export printenv
@ -455,7 +521,7 @@ complete -A alias alias unalias
complete -A function function
complete -A user su mail finger
complete -A helptopic help # currently same as builtins
complete -A helptopic help # Currently, same as builtins.
complete -A shopt shopt
complete -A stopped -P '%' bg
complete -A job -P '%' fg jobs disown
@ -472,36 +538,63 @@ complete -f -o default -X '*.+(gz|GZ)' gzip
complete -f -o default -X '!*.+(gz|GZ)' gunzip
complete -f -o default -X '*.+(bz2|BZ2)' bzip2
complete -f -o default -X '!*.+(bz2|BZ2)' bunzip2
# Postscript,pdf,dvi.....
complete -f -o default -X '!*.ps' gs ghostview ps2pdf ps2ascii
complete -f -o default -X '!*.dvi' dvips dvipdf xdvi dviselect dvitype
complete -f -o default -X '!*.pdf' acroread pdf2ps
complete -f -o default -X '!*.+(pdf|ps)' gv
complete -f -o default -X '!*.+(zip|ZIP|z|Z|gz|GZ|bz2|BZ2)' extract
# Documents - Postscript,pdf,dvi.....
complete -f -o default -X '!*.+(ps|PS)' gs ghostview ps2pdf ps2ascii
complete -f -o default -X '!*.+(dvi|DVI)' dvips dvipdf xdvi dviselect dvitype
complete -f -o default -X '!*.+(pdf|PDF)' acroread pdf2ps
complete -f -o default -X \
'!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?(.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv
complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf
complete -f -o default -X '!*.tex' tex latex slitex
complete -f -o default -X '!*.lyx' lyx
complete -f -o default -X '!*.+(htm*|HTM*)' lynx html2ps
complete -f -o default -X \
'!*.+(doc|DOC|xls|XLS|ppt|PPT|sx?|SX?|csv|CSV|od?|OD?|ott|OTT)' soffice
# Multimedia
complete -f -o default -X '!*.+(jp*g|gif|xpm|png|bmp)' xv gimp
complete -f -o default -X \
'!*.+(gif|GIF|jp*g|JP*G|bmp|BMP|xpm|XPM|png|PNG)' xv gimp ee gqview
complete -f -o default -X '!*.+(mp3|MP3)' mpg123 mpg321
complete -f -o default -X '!*.+(ogg|OGG)' ogg123
complete -f -o default -X \
'!*.@(mp[23]|MP[23]|ogg|OGG|wav|WAV|pls|m3u|xm|mod|s[3t]m|it|mtm|ult|flac)' xmms
complete -f -o default -X \
'!*.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|vcd|\
ps|pes|fli|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp3|MP3|ogg|OGG|\
ogm|OGM|mp4|MP4|wav|WAV|asx|ASX)' xine
complete -f -o default -X '!*.pl' perl perl5
# This is a 'universal' completion function - it works when commands have
# a so-called 'long options' mode , ie: 'ls --all' instead of 'ls -a'
# Needs the '-o' option of grep
# (try the commented-out version if not available).
_get_longopts ()
# First, remove '=' from completion word separators
# (this will allow completions like 'ls --color=auto' to work correctly).
COMP_WORDBREAKS=${COMP_WORDBREAKS/=/}
_get_longopts()
{
$1 --help | sed -e '/--/!d' -e 's/.*--\([^[:space:].,]*\).*/--\1/'| \
grep ^"$2" |sort -u ;
#$1 --help | sed -e '/--/!d' -e 's/.*--\([^[:space:].,]*\).*/--\1/'| \
#grep ^"$2" |sort -u ;
$1 --help | grep -o -e "--[^[:space:].,]*" | grep -e "$2" |sort -u
}
_longopts_func ()
_longopts()
{
case "${2:-*}" in
local cur
cur=${COMP_WORDS[COMP_CWORD]}
case "${cur:-*}" in
-*) ;;
*) return ;;
esac
@ -510,86 +603,143 @@ _longopts_func ()
\~*) eval cmd="$1" ;;
*) cmd="$1" ;;
esac
COMPREPLY=( $(_get_longopts ${1} ${2} ) )
COMPREPLY=( $(_get_longopts ${1} ${cur} ) )
}
complete -o default -F _longopts_func configure bash
complete -o default -F _longopts_func wget id info a2ps ls recode
complete -o default -F _longopts configure bash
complete -o default -F _longopts wget id info a2ps ls recode
_make_targets ()
_tar()
{
local mdef makef gcmd cur prev i
local cur ext regex tar untar
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
# if prev argument is -f, return possible filename completions.
# we could be a little smarter here and return matches against
# `makefile Makefile *.mk', whatever exists
case "$prev" in
-*f) COMPREPLY=( $(compgen -f $cur ) ); return 0;;
esac
# if we want an option, return the possible posix options
# If we want an option, return the possible long options.
case "$cur" in
-) COMPREPLY=(-e -f -i -k -n -p -q -r -S -s -t); return 0;;
-*) COMPREPLY=( $(_get_longopts $1 $cur ) ); return 0;;
esac
# make reads `makefile' before `Makefile'
if [ -f makefile ]; then
mdef=makefile
elif [ -f Makefile ]; then
mdef=Makefile
else
mdef=*.mk # local convention
if [ $COMP_CWORD -eq 1 ]; then
COMPREPLY=( $( compgen -W 'c t x u r d A' -- $cur ) )
return 0
fi
# before we scan for targets, see if a makefile name was specified
# with -f
case "${COMP_WORDS[1]}" in
?(-)c*f)
COMPREPLY=( $( compgen -f $cur ) )
return 0
;;
+([^Izjy])f)
ext='tar'
regex=$ext
;;
*z*f)
ext='tar.gz'
regex='t\(ar\.\)\(gz\|Z\)'
;;
*[Ijy]*f)
ext='t?(ar.)bz?(2)'
regex='t\(ar\.\)bz2\?'
;;
*)
COMPREPLY=( $( compgen -f $cur ) )
return 0
;;
esac
if [[ "$COMP_LINE" == tar*.$ext' '* ]]; then
# Complete on files in tar file.
#
# Get name of tar file from command line.
tar=$( echo "$COMP_LINE" | \
sed -e 's|^.* \([^ ]*'$regex'\) .*$|\1|' )
# Devise how to untar and list it.
untar=t${COMP_WORDS[1]//[^Izjyf]/}
COMPREPLY=( $( compgen -W "$( echo $( tar $untar $tar \
2>/dev/null ) )" -- "$cur" ) )
return 0
else
# File completion on relevant files.
COMPREPLY=( $( compgen -G $cur\*.$ext ) )
fi
return 0
}
complete -F _tar -o default tar
_make()
{
local mdef makef makef_dir="." makef_inc gcmd cur prev i;
COMPREPLY=();
cur=${COMP_WORDS[COMP_CWORD]};
prev=${COMP_WORDS[COMP_CWORD-1]};
case "$prev" in
-*f)
COMPREPLY=($(compgen -f $cur ));
return 0
;;
esac;
case "$cur" in
-*)
COMPREPLY=($(_get_longopts $1 $cur ));
return 0
;;
esac;
# make reads `GNUmakefile', then `makefile', then `Makefile'
if [ -f ${makef_dir}/GNUmakefile ]; then
makef=${makef_dir}/GNUmakefile
elif [ -f ${makef_dir}/makefile ]; then
makef=${makef_dir}/makefile
elif [ -f ${makef_dir}/Makefile ]; then
makef=${makef_dir}/Makefile
else
makef=${makef_dir}/*.mk # Local convention.
fi
# Before we scan for targets, see if a Makefile name was
# specified with -f ...
for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do
if [[ ${COMP_WORDS[i]} == -*f ]]; then
eval makef=${COMP_WORDS[i+1]} # eval for tilde expansion
if [[ ${COMP_WORDS[i]} == -f ]]; then
# eval for tilde expansion
eval makef=${COMP_WORDS[i+1]}
break
fi
done
[ ! -f $makef ] && return 0
[ -z "$makef" ] && makef=$mdef
# deal with included Makefiles
makef_inc=$( grep -E '^-?include' $makef | \
sed -e "s,^.* ,"$makef_dir"/," )
for file in $makef_inc; do
[ -f $file ] && makef="$makef $file"
done
# if we have a partial word to complete, restrict completions to
# matches of that word
if [ -n "$2" ]; then gcmd='grep "^$2"' ; else gcmd=cat ; fi
# if we don't want to use *.mk, we can take out the cat and use
# test -f $makef and input redirection
COMPREPLY=( $(cat $makef 2>/dev/null | \
awk 'BEGIN {FS=":"} /^[^.# ][^=]*:/ {print $1}' \
| tr -s ' ' '\012' | sort -u | eval $gcmd ) )
# If we have a partial word to complete, restrict completions to
# matches of that word.
if [ -n "$cur" ]; then gcmd='grep "^$cur"' ; else gcmd=cat ; fi
COMPREPLY=( $( awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \
{split($1,A,/ /);for(i in A)print A[i]}' \
$makef 2>/dev/null | eval $gcmd ))
}
complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake
complete -F _make -X '+($*|*.[cho])' make gmake pmake
# cvs(1) completion
_cvs ()
{
local cur prev
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then
COMPREPLY=( $( compgen -W 'add admin checkout commit diff \
export history import log rdiff release remove rtag status \
tag update' $cur ))
else
COMPREPLY=( $( compgen -f $cur ))
fi
return 0
}
complete -F _cvs cvs
_killall ()
_killall()
{
local cur prev
COMPREPLY=()
@ -608,62 +758,57 @@ _killall ()
complete -F _killall killall killps
# A meta-command completion function for commands like sudo(8), which
# need to first complete on a command,
# then complete according to that command's own
# completion definition - currently not quite foolproof
# (e.g. mount and umount don't work properly),
# but still quite useful --
# By Ian McDonald, modified by me.
_my_command()
# A meta-command completion function for commands like sudo(8), which need to
# first complete on a command, then complete according to that command's own
# completion definition - currently not quite foolproof,
# but still quite useful (By Ian McDonald, modified by me).
_meta_comp()
{
local cur func cline cspec
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
cmdline=${COMP_WORDS[@]}
if [ $COMP_CWORD = 1 ]; then
COMPREPLY=( $( compgen -c $cur ) )
elif complete -p ${COMP_WORDS[1]} &>/dev/null; then
cspec=$( complete -p ${COMP_WORDS[1]} )
if [ "${cspec%%-F *}" != "${cspec}" ]; then
# complete -F &lt;function&gt;
#
else
cmd=${COMP_WORDS[1]} # Find command.
cspec=$( complete -p ${cmd} ) # Find spec of that command.
# COMP_CWORD and COMP_WORDS() are not read-only,
# so we can set them before handing off to regular
# completion routine
# set current token number to 1 less than now
# completion routine:
# Get current command line minus initial command,
cline="${COMP_LINE#$1 }"
# split current command line tokens into array,
COMP_WORDS=( $cline )
# set current token number to 1 less than now.
COMP_CWORD=$(( $COMP_CWORD - 1 ))
# get function name
# If current arg is empty, add it to COMP_WORDS array
# (otherwise that information will be lost).
if [ -z $cur ]; then COMP_WORDS[COMP_CWORD]="" ; fi
if [ "${cspec%%-F *}" != "${cspec}" ]; then
# if -F then get function:
func=${cspec#*-F }
func=${func%% *}
# get current command line minus initial command
cline="${COMP_LINE#$1 }"
# split current command line tokens into array
COMP_WORDS=( $cline )
$func $cline
elif [ "${cspec#*-[abcdefgjkvu]}" != "" ]; then
# complete -[abcdefgjkvu]
#func=$( echo $cspec | sed -e 's/^.*\(-[abcdefgjkvu]\).*$/\1/' )
eval $func $cline # Evaluate it.
else
func=$( echo $cspec | sed -e 's/^complete//' -e 's/[^ ]*$//' )
COMPREPLY=( $( eval compgen $func $cur ) )
elif [ "${cspec#*-A}" != "$cspec" ]; then
# complete -A &lt;type&gt;
func=${cspec#*-A }
func=${func%% *}
COMPREPLY=( $( compgen -A $func $cur ) )
fi
else
COMPREPLY=( $( compgen -f $cur ) )
fi
}
complete -o default -F _my_command nohup exec eval \
trace truss strace sotruss gdb
complete -o default -F _my_command command type which man nice
complete -o default -F _meta_comp nohup \
eval exec trace truss strace sotruss gdb
complete -o default -F _meta_comp command type which man nice time
# Local Variables:
# mode:shell-script

View File

@ -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

View File

@ -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

View File

@ -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.
@ -117,9 +117,10 @@ echo "Elements in array8: ${array8[@]}"
# 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}.
#! What's really happening is that
#!+ the pattern matching happens after
#!+ all the other expansions of [word]
#!+ in cases like ${parameter#word}.
zap='new*'

View File

@ -1,8 +1,15 @@
#!/bin/bash
# Killing ppp to force a log-off.
# For dialup connection, of course.
# Script should be run as root user.
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.
killppp="eval kill -9 `ps ax | awk '/ppp/ { print $1 }'`"
# -------- process ID of ppp -------
@ -11,18 +18,13 @@ $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?
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..ttyS3 # Remove the serial port lock file. Why?
rm /var/lock/LCK..$SERPORT # Remove the serial port lock file. Why?
# Note:
# 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
exit $?
# Exercises:
# ---------

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -3,7 +3,7 @@
# A rudimentary man page editor
# Version: 0.1 (Alpha, probably buggy)
# Author: Mendel Cooper &lt;thegrendel@theriver.com&gt;
# Author: Mendel Cooper &lt;thegrendel.abs@gmail.com&gt;
# Reldate: 16 June 2008
# License: GPL3

View File

@ -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.

View File

@ -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!

View File

@ -1,16 +1,16 @@
#!/bin/bash
# pad.sh
######################################################
#######################################################
# PAD (xml) file creator
#+ Written by Mendel Cooper &lt;thegrendel@theriver.com&gt;.
#+ Written by Mendel Cooper &lt;thegrendel.abs@gmail.com&gt;.
#+ 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.

View File

@ -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,"

View File

@ -4,7 +4,7 @@
##############################################################
# QUACKEY: a somewhat simplified version of Perquackey [TM]. #
# #
# Author: Mendel Cooper &lt;thegrendel@theriver.com&gt; #
# Author: Mendel Cooper &lt;thegrendel.abs@gmail.com&gt; #
# 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

View File

@ -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"

View File

@ -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.

View File

@ -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.

View File

@ -23,7 +23,7 @@ IMGDIR="images" # Image directory
# Headers
HDR01='&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;'
HDR02='&lt;!-- Converted to HTML by ***tohtml.sh*** script --&gt;'
HDR03='&lt;!-- script author: M. Leo Cooper &lt;thegrendel@theriver.com&gt; --&gt;'
HDR03='&lt;!-- script author: M. Leo Cooper &lt;thegrendel.abs@gmail.com&gt; --&gt;'
HDR10='&lt;html&gt;'
HDR11='&lt;head&gt;'
HDR11a='&lt;/head&gt;'

View File

@ -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 | \