mirror of https://github.com/tLDP/LDP
updated
This commit is contained in:
parent
647f42a3c1
commit
ee92aa5778
|
@ -7,16 +7,150 @@
|
|||
|
||||
|
||||
==================================================================
|
||||
Current version = 5.3
|
||||
http://personal.riverusers.com/~thegrendel/abs-guide-5.3.tar.bz2
|
||||
Current version = 5.4
|
||||
http://personal.riverusers.com/~thegrendel/abs-guide-5.4.tar.bz2
|
||||
http://personal.riverusers.com/~thegrendel/abs-guide.pdf
|
||||
|
||||
--------------------------------------------------------------------
|
||||
News: "Petals Around the Rose" (petals.sh) example script added.
|
||||
"Crossword Puzzle Solver" (cw-solver.sh) example script added.
|
||||
"Perquackey" type game (qky.sh) example script added.
|
||||
News: "music.sh" example script added.
|
||||
"nim.sh" example script added.
|
||||
"UseGetOpt.sh" script added.
|
||||
====================================================================
|
||||
|
||||
Version 5.4, Angleberry release
|
||||
05/21/08
|
||||
|
||||
1) In "Tests" chapter:
|
||||
In "Test Constructs" section:
|
||||
Rewrote "arithmetic expansion" discussion and in-line example.
|
||||
Removed "if-echo" construct example (too confusing).
|
||||
In "File test Operators" section:
|
||||
At "-b" entry, added short usage example.
|
||||
Added a few lines to "arith-tests.sh" example.
|
||||
In "Test Comparison Operators" section:
|
||||
At "-z" entry, added short in-line example.
|
||||
|
||||
2) In "Introduction to Variables and Parameters" chapter:
|
||||
In "Variable Substitution" section,
|
||||
Added in-line example to "warning" about unassigned variables.
|
||||
Minor cleanups to introductory text.
|
||||
In "Special Variable Types" section,
|
||||
at discussion of "du" overflow, noted that this has been
|
||||
fixed as of kernel 2.6.23. (Thank you, Mauro Giachero,
|
||||
for pointing this out.)
|
||||
|
||||
3) In "Loops and Branches" chapter:
|
||||
Added in-line example of a function providing the [list]
|
||||
for a "for" loop, using command substitution.
|
||||
At "until" loops section, expanded "ex27.sh" example script.
|
||||
|
||||
4) In "Functions" chapter:
|
||||
Added comment to the effect that a function call is equivalent to a
|
||||
command.
|
||||
|
||||
5) In "Internal Commands and Builtins" chapter:
|
||||
At footnote to "getopts" entry, fixed typo.
|
||||
At "let" entry, added to "ex46.sh" example to include C-style
|
||||
increment, decrement, and trinary operators.
|
||||
|
||||
6) In "External Commands" chapter:
|
||||
In "Text Processing" section:
|
||||
At "recode" entry, fixed typo (removed extraneous ">").
|
||||
In "Math Commands" section:
|
||||
At "factor" entry, added "primes2.sh" example script.
|
||||
In "Time/Date Commands" section:
|
||||
At "sleep" entry, fixed typo in usage example.
|
||||
At "date" entry, fixup:
|
||||
delete "generate six-digit random integers" &&
|
||||
add explanation in <programlisting>
|
||||
In "File and Archiving Commands" section:
|
||||
At "more/less" entry, added paragraph (with link) explaining that
|
||||
"less" displays man page source.
|
||||
At "diff3" entry, added listing for "merge."
|
||||
In "Miscellaneous Commands" section:
|
||||
At "tee" entry, fixed typo (siponing -> siphoning).
|
||||
At "m4" entry, clarified footnote definition of "macro."
|
||||
At "getopt" entry, added Peggy Russell's note about the necessity
|
||||
of "eval."
|
||||
At "yes" entry,
|
||||
Added a use (of sorts) for parsed-variable
|
||||
echoing capability.
|
||||
Cleared up ambiguity about "yes" parsing variables (it doesn't).
|
||||
Added simple emulation of "yes" in a script function.
|
||||
In "Communications Commands" section:
|
||||
Added "mailstats" command.
|
||||
In "Terminal Commands" section:
|
||||
Added "resize" entry.
|
||||
At "tput" entry, added listing of some interesting options.
|
||||
|
||||
7) In "Arrays" chapter:
|
||||
Fixed error and typos in "array-strops.sh" example.
|
||||
Added comment line to "ex67.sh" example about ${Array[$element]}.
|
||||
(Thank you Juan Bellon, for the the heads-up on the above!)
|
||||
Revisions and fixups to "empty-array.sh" example script
|
||||
(Thank you, Nathan Coulter!)
|
||||
|
||||
8) In "Variables Revisited" chapter:
|
||||
In "Manipulating Strings" section:
|
||||
Minor rewrites to clarify meaning ("strip" --> "delete" ... etc.)
|
||||
In "Indirect References" section:
|
||||
Complete rewrite of introduction for additional clarity.
|
||||
Added material to "ind-ref.sh" example.
|
||||
In "Typing Variables" section:
|
||||
Added short in-line example to footnote.
|
||||
|
||||
9) In the "Shell Wrappers" section of "Miscellany" chapter:
|
||||
Fixed a typo in "ex3.sh" example ("This match lines ..." -->
|
||||
"This matches lines ...").
|
||||
Added mention of Martin Matusiak's "undvd" shell wrapper script.
|
||||
Added mention of Itzchak Rehberg's "Ext3Undel" package.
|
||||
|
||||
10) In "Escaping" section of "Quoting" Chapter:
|
||||
Minor fixups and clarifications.
|
||||
|
||||
11) In "/dev" section of "/dev and /proc" chapter:
|
||||
Added "music.sh" example script (plays music!). Thanks, Antonio Macchi!)
|
||||
Added links / short explanations to pseudo-device listing.
|
||||
|
||||
12) Slight stylistic revisions to "Credits" section "Endnotes" Chapter.
|
||||
|
||||
13) In "Debugging" chapter:
|
||||
Added explanations and references to listing of internal variables
|
||||
new to version 3 of Bash.
|
||||
|
||||
14) In "Restricted Shells" chapter:
|
||||
Cleaned up markup tags (changed to <itemizedlist>).
|
||||
|
||||
15) In "Assorted Tips" section of "Miscellany" chapter:
|
||||
Added "progress-bar.sh" example script. (Thanks, Dotan Barak!)
|
||||
At "rcs" entry, correction: added space to "# $Id" in 2 places.
|
||||
|
||||
16) In "Special Characters" chapter:
|
||||
At "whitespace" entry, added link to "[:space:]" POSIX character
|
||||
class.
|
||||
|
||||
17) In "Contributed Scripts" appendix:
|
||||
Added "maned.sh" -- man page editor example script.
|
||||
Added "sd.sh" -- Standard Deviation example script.
|
||||
Added "nim.sh" -- game of Nim example script.
|
||||
Added Peggy Russell's "UseGetOpt.sh" example script (thanks!).
|
||||
Slight fixup to "tohtml.sh" (more accurate conversion).
|
||||
|
||||
18) In "Writing Scripts" section of "Exercises" appendix:
|
||||
Added "Craps" exercise.
|
||||
Added "Tic-tac-toe" exercise.
|
||||
Added "Banner" exercise.
|
||||
Added "Table of Logarithms" exercise.
|
||||
|
||||
19) In "Bibliography" section:
|
||||
Added entry+link to John Lion's _Commentary_
|
||||
(still da bestest UNIX reference).
|
||||
|
||||
20) Cleanups/fixups to main text, appendices, and script examples where
|
||||
appropriate . . . especially to older scripts.
|
||||
|
||||
|
||||
|
||||
Version 5.3, Goldenberry release
|
||||
05/11/08
|
||||
|
||||
|
|
|
@ -446,6 +446,14 @@
|
|||
new notation</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><command>${!#}</command></para>
|
||||
<para><link linkend="lastargref">Final <firstterm>positional
|
||||
parameter</firstterm></link>.
|
||||
(This is an <firstterm>indirect reference</firstterm> to
|
||||
<link linkend="clacountref">$#</link>.)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><command>${!varprefix*}</command></para>
|
||||
<para><command>${!varprefix@}</command></para>
|
||||
|
@ -688,6 +696,9 @@
|
|||
<para><command>-a </command>
|
||||
<link linkend="compoundand">Logical AND</link>
|
||||
compound comparison test</para>
|
||||
<para>Address database, <link linkend="ex30">script
|
||||
example</link></para>
|
||||
|
||||
<para><firstterm>Advanced Bash Scripting Guide</firstterm>,
|
||||
<link linkend="where_tarball">where to download</link></para>
|
||||
|
||||
|
@ -707,6 +718,9 @@
|
|||
argument</link></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para><link linkend="logops1"><firstterm>And</firstterm> logical
|
||||
operator</link> <command>&&</command></para>
|
||||
|
||||
<para><link linkend="anglebrac">Angle brackets</link>,
|
||||
<firstterm>escaped</firstterm>,
|
||||
<command>\< . . . \> </command>
|
||||
|
@ -800,12 +814,13 @@
|
|||
<listitem><para>As <link linkend="retarray">
|
||||
<firstterm>return value</firstterm> from
|
||||
a function</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="arrayspecialprops">Special properties</link>,
|
||||
<firstterm>example script</firstterm></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="arraystringops">String operations</link>,
|
||||
<firstterm>example script</firstterm></para></listitem>
|
||||
|
||||
<listitem><para>Special properties,
|
||||
<link linkend="arrayspecialprops">example
|
||||
script</link></para></listitem>
|
||||
<listitem><para>String operations,
|
||||
<link linkend="arraystringops">example
|
||||
script</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="arrayunset"><firstterm>unset</firstterm> deletes array
|
||||
elements</link></para></listitem>
|
||||
|
@ -1032,6 +1047,8 @@
|
|||
|
||||
|
||||
|
||||
<para><link linkend="communications">Communications and
|
||||
hosts</link></para>
|
||||
<para><link linkend="ccomparison1">Compound comparison</link>
|
||||
operators</para>
|
||||
|
||||
|
@ -1210,8 +1227,10 @@
|
|||
external <firstterm>echo</firstterm> command</para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para><link linkend="elifref1"><command>elif</command></link>, Contraction
|
||||
of <firstterm>else</firstterm> and <firstterm>if</firstterm></para>
|
||||
<para><link linkend="elifref1">elif</link>,
|
||||
Contraction of <firstterm>else</firstterm>
|
||||
and <link linkend="ifthen">if</link></para>
|
||||
<para><link linkend="elseref">else</link></para>
|
||||
<para><link linkend="caseesac1">esac</link>, keyword terminating
|
||||
<firstterm>case</firstterm> construct</para>
|
||||
<para><link linkend="envref"><firstterm>Environmental</firstterm>
|
||||
|
@ -1235,6 +1254,8 @@
|
|||
<listitem><para><link linkend="evalforced">Forces
|
||||
<firstterm>reevaluation</firstterm></link> of
|
||||
arguments</para></listitem>
|
||||
<listitem><para>And <link linkend="evalindref">indirect
|
||||
references</link></para></listitem>
|
||||
<listitem><para><link linkend="evalrisk">Risk of
|
||||
using</link></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
@ -1268,6 +1289,9 @@
|
|||
<para><link
|
||||
linkend="exitsuccess"><firstterm>Successful</firstterm></link>,
|
||||
<command>0</command></para>
|
||||
<para><link
|
||||
linkend="sysexitsref"><filename>/usr/include/sysexits.h</filename></link>,
|
||||
system file listing C/C++ standard exit codes</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist></para>
|
||||
|
@ -1316,9 +1340,19 @@
|
|||
|
||||
<para>* * *</para>
|
||||
|
||||
<para><link linkend="factorref">factor</link>, decomposes an
|
||||
integer into its prime factors
|
||||
<itemizedlist>
|
||||
<listitem><para>Application: <link linkend="primes2">Generating
|
||||
prime numbers</link></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para><link linkend="falseref">false</link>,
|
||||
returns <firstterm>unsuccessful</firstterm> (1) <link
|
||||
linkend="exitstatusref">exit status</link></para>
|
||||
|
||||
<para><link linkend="filearchiv">Files / Archiving</link></para>
|
||||
|
||||
<para><link linkend="fdref">File descriptors</link></para>
|
||||
<itemizedlist>
|
||||
<listitem><para><link linkend="cfd">Closing</link></para>
|
||||
|
@ -1402,11 +1436,11 @@
|
|||
|
||||
<listitem>
|
||||
<para><link linkend="returnref">return</link></para>
|
||||
|
||||
<para>Multiple return values from a function,
|
||||
<link linkend="stddev">example script</link></para>
|
||||
<para><link linkend="retarray">
|
||||
Returning an <firstterm>array</firstterm></link> from
|
||||
a function</para>
|
||||
|
||||
<para><link linkend="rvt"><firstterm>return</firstterm>
|
||||
range limits</link>, workarounds</para>
|
||||
</listitem>
|
||||
|
@ -1418,6 +1452,36 @@
|
|||
|
||||
<para>* * *</para>
|
||||
|
||||
<para>Games and amusements
|
||||
<itemizedlist>
|
||||
<listitem><para><link
|
||||
linkend="agram">Anagrams</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="agram2">Anagrams</link>, again</para></listitem>
|
||||
<listitem><para><link linkend="cwsolver">Crossword puzzle
|
||||
solver</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="cryptoquote">Crypto-Quotes</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="horserace">Horse race</link></para></listitem>
|
||||
<listitem><para><link linkend="lifeslow"><quote>Life</quote>
|
||||
game</link></para></listitem>
|
||||
<listitem><para><link linkend="musicscr">Music-playing
|
||||
script</link></para></listitem>
|
||||
<listitem><para><link linkend="nim">Nim</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="brownian">Pachinko</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="qky">Perquackey</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="petals">Petals Around the Rose</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="bashpodder">Podcasting</link></para></listitem>
|
||||
<listitem><para><link linkend="poem">Poem</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="hanoi">Towers of Hanoi</link></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para><link linkend="getopty">getopt</link>,
|
||||
<firstterm>external</firstterm> command for parsing script
|
||||
<firstterm>command-line</firstterm> arguments
|
||||
|
@ -1443,6 +1507,8 @@
|
|||
<para><link linkend="gt0ref"> -gt </link>,
|
||||
<firstterm>greater-than</firstterm> <link linkend="icomparison1">integer
|
||||
comparison</link> test</para>
|
||||
<para><link linkend="groffref"><firstterm>groff</firstterm></link>,
|
||||
text markup and formatting language</para>
|
||||
<para><link linkend="groupsref"><varname>$GROUPS</varname></link>,
|
||||
<firstterm>Groups</firstterm> user belongs to</para>
|
||||
<para><link linkend="gzipref">gzip</link>, compression utility</para>
|
||||
|
@ -1538,6 +1604,10 @@
|
|||
<para>* * *</para>
|
||||
|
||||
<!-- ********************** -->
|
||||
<para><link linkend="rcsref"><varname>$Id</varname>
|
||||
parameter</link>, in <firstterm>rcs</firstterm> (Revision Control
|
||||
System)</para>
|
||||
|
||||
<para><link linkend="ifthen">if [ condition ]; then ...</link>
|
||||
<firstterm>test</firstterm> construct
|
||||
<itemizedlist>
|
||||
|
@ -1577,9 +1647,8 @@
|
|||
<para><link linkend="ivrref">Indirect referencing of variables</link>
|
||||
<itemizedlist>
|
||||
<listitem><para><link linkend="ivr2">New notation</link>, introduced
|
||||
in version 2 of Bash</para></listitem>
|
||||
<listitem><para><link linkend="varrefnew">
|
||||
Example script</link></para></listitem>
|
||||
in <link linkend="bash2ref">version 2</link> of Bash (<link
|
||||
linkend="varrefnew"> example script</link>)</para></listitem>
|
||||
</itemizedlist></para>
|
||||
<!-- ********************** -->
|
||||
|
||||
|
@ -1620,8 +1689,15 @@
|
|||
<para><link linkend="le0ref"> -le </link>,
|
||||
<firstterm>less-than or equal</firstterm>
|
||||
<link linkend="icomparison1">integer comparison</link> test</para>
|
||||
|
||||
<para><link linkend="letref">let</link>,
|
||||
setting and carrying out arithmetic operations on variables</para>
|
||||
setting and carrying out arithmetic operations on variables
|
||||
<itemizedlist>
|
||||
<listitem><para><firstterm>C-style</firstterm>
|
||||
<link linkend="ex46">increment and decrement
|
||||
operators</link></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para><link linkend="limitstringref">Limit string</link>,
|
||||
in a <link linkend="heredocref">here document</link></para>
|
||||
<para><link linkend="linenoref"><varname>$LINENO</varname></link>,
|
||||
|
@ -1775,7 +1851,9 @@
|
|||
<para><link linkend="makefileref"><filename>Makefile</filename></link>,
|
||||
file containing the list of dependencies used by <link
|
||||
linkend="makeref">make</link> command</para>
|
||||
<para><link linkend="metameaningref">meta-meaning</link></para>
|
||||
<para><link linkend="maned">Man page editor</link> (script)</para>
|
||||
<para><link linkend="mathc">Math commands</link></para>
|
||||
<para><link linkend="metameaningref">Meta-meaning</link></para>
|
||||
|
||||
<para><link linkend="moduloref">Modulo</link>, arithmetic
|
||||
<firstterm>remainder</firstterm> operator
|
||||
|
@ -1813,6 +1891,8 @@
|
|||
<para><link linkend="noclobberref"><firstterm>Noclobber</firstterm></link>,
|
||||
<option>-C</option> option to Bash to prevent overwriting
|
||||
of files</para>
|
||||
<para><link linkend="logops1"><firstterm>NOT</firstterm> logical
|
||||
operator</link>, <command>!</command></para>
|
||||
<para><link linkend="nullvar"><firstterm>null</firstterm> variable
|
||||
assignment</link>, avoiding</para>
|
||||
|
||||
|
@ -1839,8 +1919,8 @@
|
|||
linkend="setref">set</link> command</para>
|
||||
<para><link linkend="orlistref"><firstterm>Or</firstterm>
|
||||
list</link></para>
|
||||
<para><link linkend="orref">Or logical operator</link>,
|
||||
<command>||</command></para>
|
||||
<para><link linkend="orref"><firstterm>Or</firstterm> logical
|
||||
operator</link>, <command>||</command></para>
|
||||
|
||||
<para>* * *</para>
|
||||
|
||||
|
@ -2101,7 +2181,11 @@
|
|||
<para>Prime numbers
|
||||
<itemizedlist>
|
||||
<listitem><para>Generating primes
|
||||
<link linkend="primes1">without using arrays</link></para></listitem>
|
||||
<link linkend="primes2">using the <firstterm>factor</firstterm>
|
||||
command</link></para></listitem>
|
||||
<listitem><para>Generating primes
|
||||
<link linkend="primes1">using the <firstterm>modulo</firstterm>
|
||||
operator</link></para></listitem>
|
||||
<listitem><para><link linkend="primes0">Sieve of
|
||||
Eratosthenes</link></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
@ -2553,8 +2637,9 @@
|
|||
|
||||
<para><link linkend="scharlist1">Special characters</link></para>
|
||||
<para>Stack, emulating a push-down, <link
|
||||
linkend="stackex0"><firstterm>Example
|
||||
linkend="stackex0"><firstterm>example
|
||||
script</firstterm></link></para>
|
||||
<para>Standard Deviation, <link linkend="stddev">example script</link></para>
|
||||
<para><link linkend="filesref1">Startup files</link>, Bash</para>
|
||||
|
||||
<para><link linkend="stdinoutdef"><filename>stdin</filename>
|
||||
|
@ -2599,6 +2684,11 @@
|
|||
linkend="strlen">equivalent of</link></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><link linkend="stringsref">strings</link> command,
|
||||
find printable strings in a binary or data file</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Substring extraction</para>
|
||||
<para><link linkend="substrextr01">${string:position}</link></para>
|
||||
|
@ -2689,6 +2779,8 @@
|
|||
|
||||
<para>* * *</para>
|
||||
|
||||
<para>Table lookup, <link linkend="resistor">script
|
||||
example</link></para>
|
||||
<para><link linkend="tailref">tail</link>, <firstterm>echo</firstterm>
|
||||
to <filename>stdout</filename> lines at the (tail) end of a text
|
||||
file</para>
|
||||
|
@ -2697,13 +2789,14 @@
|
|||
output of command(s) partway through a <link
|
||||
linkend="piperef">pipe</link></para>
|
||||
|
||||
<para><link linkend="terminalsref">Terminals</link>
|
||||
<para><link linkend="terminalssys1">Terminals</link>
|
||||
<itemizedlist>
|
||||
<listitem><para><link
|
||||
linkend="setserialref">setserial</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="settermref">setterm</link></para></listitem>
|
||||
<listitem><para><link linkend="sttyref">stty</link></para></listitem>
|
||||
<listitem><para><link linkend="tputref">tput</link></para></listitem>
|
||||
<listitem><para><link linkend="wallref">wall</link></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
|
@ -2813,6 +2906,12 @@
|
|||
</listitem>
|
||||
|
||||
</itemizedlist></para>
|
||||
<!-- *************************************************************** -->
|
||||
|
||||
<para><link linkend="textproc">Text and text file
|
||||
processing</link></para>
|
||||
<para><link linkend="timedate">Time / Date</link></para>
|
||||
|
||||
<!-- *************************************************************** -->
|
||||
<para>Timed input
|
||||
<itemizedlist>
|
||||
|
@ -2879,14 +2978,16 @@
|
|||
<listitem><para><link
|
||||
linkend="prependref"><firstterm>Prepending</firstterm></link>
|
||||
lines at head of a file</para></listitem>
|
||||
<listitem><para><link linkend="progressbar">Progress
|
||||
bar</link> template</para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="pseudocoderef">Pseudo-code</link></para></listitem>
|
||||
<listitem><para>Script<link linkend="scriptasemb"> as embedded
|
||||
command</link></para></listitem>
|
||||
<listitem><para><link linkend="rcsref">rcs</link></para></listitem>
|
||||
<listitem><para><link linkend="runpartsref2">Running scripts in
|
||||
sequence</link> without user intervention, using <link
|
||||
linkend="runpartsref">run-parts</link></para></listitem>
|
||||
<listitem><para>Script<link linkend="scriptasemb"> as embedded
|
||||
command</link></para></listitem>
|
||||
<listitem>
|
||||
<para>Script <firstterm>portability</firstterm></para>
|
||||
<para><link
|
||||
|
@ -2916,7 +3017,9 @@
|
|||
|
||||
|
||||
<para><link linkend="tmoutref"><varname>$TMOUT</varname></link>,
|
||||
Timeout interval</para>
|
||||
Timeout interval</para>
|
||||
<para><link linkend="tputref">tput</link>, terminal-control
|
||||
command</para>
|
||||
|
||||
<para><link linkend="trref">tr</link>, character translation filter
|
||||
<itemizedlist>
|
||||
|
@ -2934,8 +3037,18 @@
|
|||
<para><link linkend="trapref1"><firstterm>Trap</firstterm></link>,
|
||||
specifying an action upon receipt of a <link
|
||||
linkend="signald">signal</link></para>
|
||||
<para><link linkend="cstrinary">Trinary operator</link>,
|
||||
<firstterm>C</firstterm>-style</para>
|
||||
|
||||
<para><firstterm>Trinary</firstterm> operator,
|
||||
<firstterm>C</firstterm>-style,
|
||||
<userinput>var>10?88:99</userinput>
|
||||
<itemizedlist>
|
||||
<listitem><para><link linkend="cstrinary">in
|
||||
<firstterm>double-parentheses</firstterm>
|
||||
construct</link></para></listitem>
|
||||
<listitem><para><link linkend="ex46">in <firstterm>let</firstterm>
|
||||
construct</link></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para><link linkend="trueref">true</link>,
|
||||
returns <firstterm>successful</firstterm> (0) <link
|
||||
linkend="exitstatusref">exit status</link></para>
|
||||
|
@ -3077,6 +3190,15 @@
|
|||
<para><link linkend="whileloopref">while</link> loop</para>
|
||||
<para><firstterm>while [ condition ]; do</firstterm>
|
||||
<itemizedlist>
|
||||
<listitem><para><link linkend="whloopc">C-style syntax</link>
|
||||
</para></listitem>
|
||||
<listitem><para><link linkend="whilefunc">Calling a
|
||||
<firstterm>function</firstterm> within
|
||||
<firstterm>test</firstterm> brackets</link></para></listitem>
|
||||
<listitem><para><link linkend="whmultcond">Multiple
|
||||
conditions</link></para></listitem>
|
||||
<listitem><para><link linkend="whilenobrackets">Omitting
|
||||
<firstterm>test</firstterm> brackets</link></para></listitem>
|
||||
<listitem><para><link linkend="whilereadref2">
|
||||
<firstterm>while read</firstterm></link>
|
||||
construct</para></listitem>
|
||||
|
@ -3094,10 +3216,12 @@
|
|||
document</firstterm>, error</para></listitem>
|
||||
<listitem><para><link linkend="wsbcomm">Preceding script
|
||||
comments</link></para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="wsquo"><firstterm>Quoting</firstterm></link>,
|
||||
to preserve <firstterm>whitespace</firstterm> within strings
|
||||
or variables</para></listitem>
|
||||
<listitem><para><link
|
||||
linkend="wsquo"><firstterm>Quoting</firstterm></link>,
|
||||
to preserve <firstterm>whitespace</firstterm> within strings
|
||||
or variables</para></listitem>
|
||||
<listitem><para><link linkend="wsposix">[:space:]</link>,
|
||||
<firstterm>POSIX</firstterm> character class</para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para><link linkend="whoref">who</link>, information about logged on users
|
||||
|
@ -3129,7 +3253,11 @@
|
|||
|
||||
<para>* * *</para>
|
||||
|
||||
<para><link linkend="yesref">yes</link></para>
|
||||
<para><link linkend="yesref">yes</link>
|
||||
<itemizedlist>
|
||||
<listitem><para><link
|
||||
linkend="yesemu">Emulation</link></para></listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
<para>* * *</para>
|
||||
|
||||
|
|
|
@ -93,12 +93,24 @@ tree2.sh:
|
|||
line 88
|
||||
|
||||
petals.sh
|
||||
line 54
|
||||
line 56
|
||||
|
||||
realname.sh
|
||||
line 26
|
||||
|
||||
qky.sh
|
||||
line 7
|
||||
line 63
|
||||
line 87
|
||||
line 113
|
||||
(The unaltered, executable script can be downloaded from
|
||||
http://personal.riverusers.com/~thegrendel/qky.sh)
|
||||
(The unaltered, executable script can be downloaded. See:
|
||||
http://personal.riverusers.com/~thegrendel/qky.README.html)
|
||||
|
||||
maned.sh
|
||||
line 6 (comment)
|
||||
|
||||
progress-bar.sh
|
||||
line 26
|
||||
line 30
|
||||
nim.sh
|
||||
line 27
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
#!/bin/bash
|
||||
# UseGetOpt.sh
|
||||
|
||||
# Author: Peggy Russell <prusselltechgroup@gmail.com>
|
||||
|
||||
UseGetOpt () {
|
||||
declare inputOptions
|
||||
declare -r E_OPTERR=85
|
||||
declare -r ScriptName=${0##*/}
|
||||
declare -r ShortOpts="adf:hlt"
|
||||
declare -r LongOpts="aoption,debug,file:,help,log,test"
|
||||
|
||||
DoSomething () {
|
||||
echo "The function name is '${FUNCNAME}'"
|
||||
# Recall that $FUNCNAME is an internal variable
|
||||
#+ holding the name of the function it is in.
|
||||
}
|
||||
|
||||
inputOptions=$(getopt -o "${ShortOpts}" --long \
|
||||
"${LongOpts}" --name "${ScriptName}" -- "${@}")
|
||||
|
||||
if [[ ($? -ne 0) || ($# -eq 0) ]]; then
|
||||
echo "Usage: ${ScriptName} [-dhlt] {OPTION...}"
|
||||
exit $E_OPTERR
|
||||
fi
|
||||
|
||||
eval set -- "${inputOptions}"
|
||||
|
||||
# Only for educational purposes. Can be removed.
|
||||
#-----------------------------------------------
|
||||
echo "++ Test: Number of arguments: [$#]"
|
||||
echo '++ Test: Looping through "$@"'
|
||||
for a in "$@"; do
|
||||
echo " ++ [$a]"
|
||||
done
|
||||
#-----------------------------------------------
|
||||
|
||||
while true; do
|
||||
case "${1}" in
|
||||
--aoption | -a) # Argument found.
|
||||
echo "Option [$1]"
|
||||
;;
|
||||
|
||||
--debug | -d) # Enable informational messages.
|
||||
echo "Option [$1] Debugging enabled"
|
||||
;;
|
||||
|
||||
--file | -f) # Check for optional argument.
|
||||
case "$2" in #+ Double colon is optional argument.
|
||||
"") # Not there.
|
||||
echo "Option [$1] Use default"
|
||||
shift
|
||||
;;
|
||||
|
||||
*) # Got it
|
||||
echo "Option [$1] Using input [$2]"
|
||||
shift
|
||||
;;
|
||||
|
||||
esac
|
||||
DoSomething
|
||||
;;
|
||||
|
||||
--log | -l) # Enable Logging.
|
||||
echo "Option [$1] Logging enabled"
|
||||
;;
|
||||
|
||||
--test | -t) # Enable testing.
|
||||
echo "Option [$1] Testing enabled"
|
||||
;;
|
||||
|
||||
--help | -h)
|
||||
echo "Option [$1] Display help"
|
||||
break
|
||||
;;
|
||||
|
||||
--) # Done! $# is argument number for "--", $@ is "--"
|
||||
echo "Option [$1] Dash Dash"
|
||||
break
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Major internal error!"
|
||||
exit 8
|
||||
;;
|
||||
|
||||
esac
|
||||
echo "Number of arguments: [$#]"
|
||||
shift
|
||||
done
|
||||
|
||||
shift
|
||||
# Only for educational purposes. Can be removed.
|
||||
#----------------------------------------------------------------------
|
||||
echo "++ Test: Number of arguments after \"--\" is [$#] They are: [$@]"
|
||||
echo '++ Test: Looping through "$@"'
|
||||
for a in "$@"; do
|
||||
echo " ++ [$a]"
|
||||
done
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
################################### M A I N ########################
|
||||
# If you remove "function UseGetOpt () {" and corresponding "}",
|
||||
#+ you can uncomment the "exit 0" line below, and invoke this script
|
||||
#+ with the various options from the command line.
|
||||
#-------------------------------------------------------------------
|
||||
# exit 0
|
||||
|
||||
echo "Test 1"
|
||||
UseGetOpt -f myfile one "two three" four
|
||||
|
||||
echo;echo "Test 2"
|
||||
UseGetOpt -h
|
||||
|
||||
echo;echo "Test 3 - Short Options"
|
||||
UseGetOpt -adltf myfile anotherfile
|
||||
|
||||
echo;echo "Test 4 - Long Options"
|
||||
UseGetOpt --aoption --debug --log --test --file myfile anotherfile
|
||||
|
||||
exit
|
File diff suppressed because it is too large
Load Diff
|
@ -38,4 +38,4 @@ chmod 777 $MOUNTPOINT # Makes new drive accessible to all users.
|
|||
# Add the following line to /etc/fstab.
|
||||
# /dev/hdb1 /mnt/newdisk ext2 defaults 1 1
|
||||
|
||||
exit 0
|
||||
exit
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
# allprofs.sh: print all user profiles
|
||||
# allprofs.sh: Print all user profiles.
|
||||
|
||||
# This script written by Heiner Steven, and modified by the document author.
|
||||
|
||||
|
|
|
@ -34,4 +34,16 @@ echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1
|
|||
# What would happen if it were removed?
|
||||
# Try removing it, then rerunning the script.
|
||||
|
||||
# ======================================= #
|
||||
|
||||
# (( ... )) also useful in an if-then test.
|
||||
|
||||
var1=5
|
||||
var2=4
|
||||
|
||||
if (( var1 > var2 ))
|
||||
then #^ ^ Note: Not $var1, $var2. Why?
|
||||
echo "$var1 is greater than $var2"
|
||||
fi # 5 is greater than 4
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#!/bin/bash
|
||||
# array-strops.sh: String operations on arrays.
|
||||
# Script by Michael Zick.
|
||||
# Used with permission.
|
||||
|
||||
# In general, any string operation in the ${name ... } notation
|
||||
#+ can be applied to all string elements in an array
|
||||
# Script by Michael Zick.
|
||||
# Fixups: 05 May 08
|
||||
# Used in ABS Guide with permission.
|
||||
|
||||
# In general, any string operation using the ${name ... } notation
|
||||
#+ can be applied to all string elements in an array,
|
||||
#+ with the ${name[@] ... } or ${name[*] ...} notation.
|
||||
|
||||
|
||||
|
@ -14,19 +16,20 @@ echo
|
|||
|
||||
# Trailing Substring Extraction
|
||||
echo ${arrayZ[@]:0} # one two three four five five
|
||||
# All elements.
|
||||
# ^ All elements.
|
||||
|
||||
echo ${arrayZ[@]:1} # two three four five five
|
||||
# All elements following element[0].
|
||||
# ^ All elements following element[0].
|
||||
|
||||
echo ${arrayZ[@]:1:2} # two three
|
||||
# Only the two elements after element[0].
|
||||
# ^ Only the two elements after element[0].
|
||||
|
||||
echo "-----------------------"
|
||||
|
||||
# Substring Removal
|
||||
# Removes shortest match from front of string(s),
|
||||
#+ where the substring is a regular expression.
|
||||
|
||||
# Substring Removal
|
||||
|
||||
# Removes shortest match from front of string(s).
|
||||
|
||||
echo ${arrayZ[@]#f*r} # one two three five five
|
||||
# Applied to all elements of the array.
|
||||
|
@ -51,54 +54,61 @@ echo "-----------------------"
|
|||
|
||||
# Substring Replacement
|
||||
|
||||
# Replace first occurance of substring with replacement
|
||||
# Replace first occurrence of substring with replacement.
|
||||
echo ${arrayZ[@]/fiv/XYZ} # one two three four XYZe XYZe
|
||||
# Applied to all elements of the array.
|
||||
# ^ ^^^ ^^^ Applied to all elements of the array.
|
||||
|
||||
# Replace all occurances of substring
|
||||
# Replace all occurrences of substring.
|
||||
echo ${arrayZ[@]//iv/YY} # one two three four fYYe fYYe
|
||||
# Applied to all elements of the array.
|
||||
|
||||
# Delete all occurances of substring
|
||||
# Not specifing a replacement means 'delete'
|
||||
# Delete all occurrences of substring.
|
||||
# Not specifing a replacement means 'delete.'
|
||||
echo ${arrayZ[@]//fi/} # one two three four ve ve
|
||||
# Applied to all elements of the array.
|
||||
# ^^ Applied to all elements of the array.
|
||||
|
||||
# Replace front-end occurances of substring
|
||||
# Replace front-end occurrences of substring.
|
||||
echo ${arrayZ[@]/#fi/XY} # one two three four XYve XYve
|
||||
# Applied to all elements of the array.
|
||||
# ^ Applied to all elements of the array.
|
||||
|
||||
# Replace back-end occurances of substring
|
||||
# Replace back-end occurrences of substring.
|
||||
echo ${arrayZ[@]/%ve/ZZ} # one two three four fiZZ fiZZ
|
||||
# Applied to all elements of the array.
|
||||
# ^ Applied to all elements of the array.
|
||||
|
||||
echo ${arrayZ[@]/%o/XX} # one twXX three four five five
|
||||
# Why?
|
||||
# ^ Why?
|
||||
|
||||
echo "-----------------------"
|
||||
|
||||
|
||||
# Before reaching for awk (or anything else) --
|
||||
# Recall:
|
||||
# $( ... ) is command substitution.
|
||||
# Functions run as a sub-process.
|
||||
# Functions write their output to stdout.
|
||||
# Assignment reads the function's stdout.
|
||||
# The name[@] notation specifies a "for-each" operation.
|
||||
|
||||
newstr() {
|
||||
echo -n "!!!"
|
||||
}
|
||||
|
||||
echo ${arrayZ[@]/%e/$(newstr)}
|
||||
# ^ ^^^^^^^^^
|
||||
# on!!! two thre!!! four fiv!!! fiv!!!
|
||||
# Q.E.D: The replacement action is an 'assignment.'
|
||||
# Q.E.D: The replacement action is, in effect, an 'assignment.'
|
||||
|
||||
echo "-----------------------"
|
||||
|
||||
# Accessing the "For-Each"
|
||||
echo ${arrayZ[@]//*/$(newstr optional_arguments)}
|
||||
# Now, if Bash would just pass the matched string as $0
|
||||
# !!! !!! !!! !!! !!! !!!
|
||||
|
||||
# Now, if Bash would only pass the matched string
|
||||
#+ to the function being called . . .
|
||||
|
||||
echo
|
||||
|
||||
exit 0
|
||||
|
||||
# Before reaching for a Big Hammer -- awk, Perl, or anything else --
|
||||
# recall:
|
||||
# $( ... ) is command substitution.
|
||||
# A function runs as a sub-process.
|
||||
# A function writes its output to stdout.
|
||||
# Assignment, in conjunction with 'echo' and command substitution,
|
||||
#+ can read a function's stdout.
|
||||
# The name[@] notation specifies a "for-each" operation.
|
||||
# Bash is more powerful than you think!
|
||||
|
|
|
@ -10,7 +10,8 @@ exit 0
|
|||
# =======================================================
|
||||
|
||||
#!/usr/bin/perl
|
||||
# This part of the script must be invoked with -x option.
|
||||
# This part of the script must be invoked with
|
||||
# perl -x bashandperl.sh
|
||||
|
||||
print "Greetings from the Perl part of the script.\n";
|
||||
# More Perl commands may follow here.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#! /bin/sh
|
||||
# Strips off the header from a mail/News message i.e. till the first
|
||||
# empty line
|
||||
# Mark Moraes, University of Toronto
|
||||
# empty line.
|
||||
# Author: Mark Moraes, University of Toronto
|
||||
# See the included file "Moraes-COPYRIGHT" for copyright info.
|
||||
|
||||
# ==> These comments added by author of this document.
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ Move () { # Move one unit right / left, or stay put.
|
|||
|
||||
Play () { # Single pass (inner loop).
|
||||
i=0
|
||||
while [ "$i" -lt "$ROWS" ] # One event per row.
|
||||
while [ "$i" -lt "$ROWS" ] # One event per row.
|
||||
do
|
||||
Move
|
||||
((i++));
|
||||
|
|
|
@ -1,31 +1,32 @@
|
|||
#!/bin/bash
|
||||
# Manipulating a variable, C-style, using the ((...)) construct.
|
||||
# c-vars.sh
|
||||
# Manipulating a variable, C-style, using the (( ... )) construct.
|
||||
|
||||
|
||||
echo
|
||||
|
||||
(( a = 23 )) # Setting a value, C-style,
|
||||
#+ with spaces on both sides of the "=".
|
||||
echo "a (initial value) = $a"
|
||||
echo "a (initial value) = $a" # 23
|
||||
|
||||
(( a++ )) # Post-increment 'a', C-style.
|
||||
echo "a (after a++) = $a"
|
||||
echo "a (after a++) = $a" # 24
|
||||
|
||||
(( a-- )) # Post-decrement 'a', C-style.
|
||||
echo "a (after a--) = $a"
|
||||
echo "a (after a--) = $a" # 23
|
||||
|
||||
|
||||
(( ++a )) # Pre-increment 'a', C-style.
|
||||
echo "a (after ++a) = $a"
|
||||
echo "a (after ++a) = $a" # 24
|
||||
|
||||
(( --a )) # Pre-decrement 'a', C-style.
|
||||
echo "a (after --a) = $a"
|
||||
echo "a (after --a) = $a" # 23
|
||||
|
||||
echo
|
||||
|
||||
########################################################
|
||||
# Note that, as in C, pre- and post-decrement operators
|
||||
#+ have slightly different side-effects.
|
||||
#+ have different side-effects.
|
||||
|
||||
n=1; let --n && echo "True" || echo "False" # False
|
||||
n=1; let n-- && echo "True" || echo "False" # True
|
||||
|
@ -37,8 +38,8 @@ echo
|
|||
|
||||
(( t = a<45?7:11 )) # C-style trinary operator.
|
||||
# ^ ^ ^
|
||||
echo "If a < 45, then t = 7, else t = 11."
|
||||
echo "t = $t " # Yes!
|
||||
echo "If a < 45, then t = 7, else t = 11." # a = 23
|
||||
echo "t = $t " # t = 7
|
||||
|
||||
echo
|
||||
|
||||
|
@ -48,12 +49,12 @@ echo
|
|||
# -----------------
|
||||
# Chet Ramey seems to have snuck a bunch of undocumented C-style
|
||||
#+ constructs into Bash (actually adapted from ksh, pretty much).
|
||||
# In the Bash docs, Ramey calls ((...)) shell arithmetic,
|
||||
# In the Bash docs, Ramey calls (( ... )) shell arithmetic,
|
||||
#+ but it goes far beyond that.
|
||||
# Sorry, Chet, the secret is now out.
|
||||
# Sorry, Chet, the secret is out.
|
||||
|
||||
# See also "for" and "while" loops using the ((...)) construct.
|
||||
# See also "for" and "while" loops using the (( ... )) construct.
|
||||
|
||||
# These work only with Bash, version 2.04 or later.
|
||||
# These work only with version 2.04 or later of Bash.
|
||||
|
||||
exit 0
|
||||
exit
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#!/bin/bash
|
||||
# This is a slight modification of the example file in the "column" man page.
|
||||
# colms.sh
|
||||
# A minor modification of the example file in the "column" man page.
|
||||
|
||||
|
||||
(printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n" \
|
||||
; ls -l | sed 1d) | column -t
|
||||
# ^^^^^^ ^^
|
||||
|
||||
# The "sed 1d" in the pipe deletes the first line of output,
|
||||
#+ which would be "total N",
|
||||
|
|
|
@ -5,7 +5,9 @@ PROCFILENAME=status # Where to look.
|
|||
NOTCONNECTED=65
|
||||
INTERVAL=2 # Update every 2 seconds.
|
||||
|
||||
pidno=$( ps ax | grep -v "ps ax" | grep -v grep | grep $PROCNAME | awk '{ print $1 }' )
|
||||
pidno=$( ps ax | grep -v "ps ax" | grep -v grep | grep $PROCNAME |
|
||||
awk '{ print $1 }' )
|
||||
|
||||
# Finding the process number of 'pppd', the 'ppp daemon'.
|
||||
# Have to filter out the process lines generated by the search itself.
|
||||
#
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
# cw-solver.sh
|
||||
# This is actually a wrapper around a one-liner (line 46).
|
||||
|
||||
# Crossword puzzle and anagramming word game solver.
|
||||
# You know *some* of the letters in the word you're looking for,
|
||||
|
@ -34,7 +35,7 @@ then #+ as a command-line argument . . .
|
|||
echo "The x's represent known letters,"
|
||||
echo "and the periods are unknown letters (blanks)."
|
||||
echo "Letters and periods can be in any position."
|
||||
echo "For example, try: cw-solver.sh w...i....n"
|
||||
echo "For example, try: sh cw-solver.sh w...i....n"
|
||||
echo
|
||||
exit $E_NOPATT
|
||||
fi
|
||||
|
@ -49,7 +50,7 @@ grep ^"$1"$ "$DICT" # Yes, only one line!
|
|||
|
||||
# From _Stupid Grep Tricks_, vol. 1,
|
||||
#+ a book the ABS Guide author may yet get around
|
||||
#+ to writing one of these days . . .
|
||||
#+ to writing . . . one of these days . . .
|
||||
# ===============================================
|
||||
echo
|
||||
|
||||
|
@ -58,9 +59,8 @@ exit $? # Script terminates here.
|
|||
# If there are too many words generated,
|
||||
#+ redirect the output to a file.
|
||||
|
||||
cw-solver w...i....n
|
||||
$ sh cw-solver.sh w...i....n
|
||||
|
||||
twichildren
|
||||
wellington
|
||||
workingman
|
||||
workingmen
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
# empty-array.sh
|
||||
|
||||
# Thanks to Stephane Chazelas for the original example,
|
||||
#+ and to Michael Zick and Omair Eshkenazi for extending it.
|
||||
#+ and to Michael Zick, Omair Eshkenazi, for extending it.
|
||||
# And to Nathan Coulter for clarifications and corrections.
|
||||
|
||||
|
||||
# An empty array is not the same as an array with empty elements.
|
||||
|
@ -12,6 +13,7 @@
|
|||
array2=( ) # No elements . . . "array2" is empty.
|
||||
array3=( ) # What about this array?
|
||||
|
||||
|
||||
echo
|
||||
ListArray()
|
||||
{
|
||||
|
@ -54,8 +56,8 @@ array3[${#array3[*]}]="new2"
|
|||
|
||||
ListArray
|
||||
|
||||
# When extended as above; arrays are 'stacks'
|
||||
# The above is the 'push'
|
||||
# When extended as above, arrays are 'stacks' ...
|
||||
# Above is the 'push' ...
|
||||
# The stack 'height' is:
|
||||
height=${#array2[@]}
|
||||
echo
|
||||
|
@ -71,7 +73,7 @@ echo "New stack height for array2 = $height"
|
|||
ListArray
|
||||
|
||||
# List only 2nd and 3rd elements of array0.
|
||||
from=1 # Zero-based numbering.
|
||||
from=1 # Zero-based numbering.
|
||||
to=2
|
||||
array3=( ${array0[@]:1:2} )
|
||||
echo
|
||||
|
@ -108,25 +110,47 @@ echo "Elements in array8: ${array8[@]}"
|
|||
|
||||
# The string operations are performed on
|
||||
#+ each of the elements in var[@] in succession.
|
||||
# Therefore : Bash supports string vector operations
|
||||
#+ if the result is a zero length string,
|
||||
# Therefore : Bash supports string vector operations.
|
||||
# If the result is a zero length string,
|
||||
#+ that element disappears in the resulting assignment.
|
||||
# However, if the expansion is in quotes, the null elements remain.
|
||||
|
||||
# Michael Zick: Question, are those strings hard or soft quotes?
|
||||
# Nathan Coulter: There is no such thing as "soft quotes."
|
||||
# What's really happening is that
|
||||
#+ the pattern matching happens after all the other expansions of [word]
|
||||
#+ in cases like ${parameter#word}.
|
||||
|
||||
# Question, are those strings hard or soft quotes?
|
||||
|
||||
zap='new*'
|
||||
array9=( ${array0[@]/$zap/} )
|
||||
echo
|
||||
echo "Number of elements in array9: ${#array9[@]}"
|
||||
array9=( "${array0[@]/$zap/}" )
|
||||
echo "Elements in array9: ${array9[@]}"
|
||||
# This time the null elements remain.
|
||||
echo "Number of elements in array9: ${#array9[@]}"
|
||||
|
||||
# Just when you thought you where still in Kansas . . .
|
||||
array10=( ${array0[@]#$zap} )
|
||||
|
||||
# Just when you thought you were still in Kansas . . .
|
||||
array10=( ${array0[@]#"$zap"} )
|
||||
echo
|
||||
echo "Elements in array10: ${array10[@]}"
|
||||
# But, the asterisk in zap won't be interpreted if quoted.
|
||||
array10=( ${array0[@]#"$zap"} )
|
||||
echo
|
||||
echo "Elements in array10: ${array10[@]}"
|
||||
# Well, maybe we _are_ still in Kansas . . .
|
||||
# (Revisions to above code block by Nathan Coulter.)
|
||||
|
||||
# Compare array7 with array10.
|
||||
# Compare array8 with array9.
|
||||
|
||||
# Answer: must be soft quotes.
|
||||
# Compare array7 with array10.
|
||||
# Compare array8 with array9.
|
||||
|
||||
exit 0
|
||||
# Reiterating: No such thing as soft quotes!
|
||||
# Nathan Coulter's explains:
|
||||
# Pattern matching of 'word' in ${parameter#word} is done after
|
||||
#+ parameter expansion and *before* quote removal.
|
||||
# In the normal case, pattern matching is done *after* quote removal.
|
||||
|
||||
exit
|
||||
|
|
|
@ -10,7 +10,7 @@ echo "Testing \"0\""
|
|||
if [ 0 ] # zero
|
||||
then
|
||||
echo "0 is true."
|
||||
else
|
||||
else # Or else ...
|
||||
echo "0 is false."
|
||||
fi # 0 is true.
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
#!/bin/bash
|
||||
# zmore
|
||||
|
||||
#View gzipped files with 'more'
|
||||
# View gzipped files with 'more' filter.
|
||||
|
||||
NOARGS=65
|
||||
NOTFOUND=66
|
||||
NOTGZIP=67
|
||||
E_NOARGS=65
|
||||
E_NOTFOUND=66
|
||||
E_NOTGZIP=67
|
||||
|
||||
if [ $# -eq 0 ] # same effect as: if [ -z "$1" ]
|
||||
# $1 can exist, but be empty: zmore "" arg2 arg3
|
||||
then
|
||||
echo "Usage: `basename $0` filename" >&2
|
||||
# Error message to stderr.
|
||||
exit $NOARGS
|
||||
exit $E_NOARGS
|
||||
# Returns 65 as exit status of script (error code).
|
||||
fi
|
||||
|
||||
|
@ -20,24 +20,22 @@ filename=$1
|
|||
|
||||
if [ ! -f "$filename" ] # Quoting $filename allows for possible spaces.
|
||||
then
|
||||
echo "File $filename not found!" >&2
|
||||
# Error message to stderr.
|
||||
exit $NOTFOUND
|
||||
echo "File $filename not found!" >&2 # Error message to stderr.
|
||||
exit $E_NOTFOUND
|
||||
fi
|
||||
|
||||
if [ ${filename##*.} != "gz" ]
|
||||
# Using bracket in variable substitution.
|
||||
then
|
||||
echo "File $1 is not a gzipped file!"
|
||||
exit $NOTGZIP
|
||||
exit $E_NOTGZIP
|
||||
fi
|
||||
|
||||
zcat $1 | more
|
||||
|
||||
# Uses the filter 'more.'
|
||||
# May substitute 'less', if desired.
|
||||
|
||||
# Uses the 'more' filter.
|
||||
# May substitute 'less' if desired.
|
||||
|
||||
exit $? # Script returns exit status of pipe.
|
||||
# Actually "exit $?" is unnecessary, as the script will, in any case,
|
||||
# return the exit status of the last command executed.
|
||||
# Actually "exit $?" is unnecessary, as the script will, in any case,
|
||||
#+ return the exit status of the last command executed.
|
||||
|
|
|
@ -12,4 +12,19 @@ do
|
|||
echo
|
||||
done
|
||||
|
||||
# ------------------------------------------- #
|
||||
|
||||
# As with "for" and "while" loops,
|
||||
#+ an "until" loop permits C-like test constructs.
|
||||
|
||||
LIMIT=10
|
||||
var=0
|
||||
|
||||
until (( var > LIMIT ))
|
||||
do # ^^ ^ ^ ^^ No brackets, no $ prefixing variables.
|
||||
echo -n "$var "
|
||||
(( var++ ))
|
||||
done # 0 1 2 3 4 5 6 7 8 9 10
|
||||
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
# This is a simple script that removes blank lines from a file.
|
||||
# This simple script removes blank lines from a file.
|
||||
# No argument checking.
|
||||
#
|
||||
# You might wish to add something like:
|
||||
#
|
||||
# E_NOARGS=65
|
||||
# E_NOARGS=85
|
||||
# if [ -z "$1" ]
|
||||
# then
|
||||
# echo "Usage: `basename $0` target-file"
|
||||
|
@ -13,14 +13,15 @@
|
|||
# fi
|
||||
|
||||
|
||||
|
||||
sed -e /^$/d "$1"
|
||||
# Same as
|
||||
# sed -e '/^$/d' filename
|
||||
# invoked from the command line.
|
||||
|
||||
sed -e /^$/d "$1"
|
||||
# The '-e' means an "editing" command follows (optional here).
|
||||
# '^' is the beginning of line, '$' is the end.
|
||||
# This match lines with nothing between the beginning and the end,
|
||||
# '^' indicates the beginning of line, '$' the end.
|
||||
# This matches lines with nothing between the beginning and the end --
|
||||
#+ blank lines.
|
||||
# The 'd' is the delete command.
|
||||
|
||||
|
@ -30,4 +31,4 @@ sed -e /^$/d "$1"
|
|||
# Note that this script doesn't actually change the target file.
|
||||
# If you need to do that, redirect its output.
|
||||
|
||||
exit 0
|
||||
exit
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#!/bin/bash
|
||||
|
||||
# "subst", a script that substitutes one pattern for
|
||||
# subst.sh: a script that substitutes one pattern for
|
||||
#+ another in a file,
|
||||
#+ i.e., "subst Smith Jones letter.txt".
|
||||
#+ i.e., "sh subst.sh Smith Jones letter.txt".
|
||||
# Jones replaces Smith.
|
||||
|
||||
ARGS=3 # Script requires 3 arguments.
|
||||
E_BADARGS=65 # Wrong number of arguments passed to script.
|
||||
E_BADARGS=85 # Wrong number of arguments passed to script.
|
||||
|
||||
if [ $# -ne "$ARGS" ]
|
||||
# Test number of arguments to script (always a good idea).
|
||||
|
@ -26,16 +27,15 @@ else
|
|||
fi
|
||||
|
||||
|
||||
# Here is where the heavy work gets done.
|
||||
|
||||
# -----------------------------------------------
|
||||
# Here is where the heavy work gets done.
|
||||
sed -e "s/$old_pattern/$new_pattern/g" $file_name
|
||||
# -----------------------------------------------
|
||||
|
||||
# 's' is, of course, the substitute command in sed,
|
||||
#+ and /pattern/ invokes address matching.
|
||||
# The "g", or global flag causes substitution for *every*
|
||||
# The 'g,' or global flag causes substitution for EVERY
|
||||
#+ occurence of $old_pattern on each line, not just the first.
|
||||
# Read the literature on 'sed' for an in-depth explanation.
|
||||
# Read the 'sed' docs for an in-depth explanation.
|
||||
|
||||
exit 0 # Successful invocation of the script returns 0.
|
||||
exit $?
|
||||
|
|
|
@ -24,6 +24,26 @@ let "a %= 8" # Equivalent to let "a = a % 8"
|
|||
echo "270 modulo 8 = $a (270 / 8 = 33, remainder $a)"
|
||||
# 6
|
||||
|
||||
|
||||
# Does "let" permit C-style operators?
|
||||
# Yes, just as the (( ... )) double-parentheses construct does.
|
||||
|
||||
let a++ # C-style (post) increment.
|
||||
echo "6++ = $a" # 6++ = 7
|
||||
let a-- # C-style decrement.
|
||||
echo "7-- = $a" # 7-- = 6
|
||||
# Of course, ++a, etc., also allowed . . .
|
||||
echo
|
||||
|
||||
exit 0
|
||||
|
||||
# Trinary operator.
|
||||
|
||||
# Note that $a is 6, see above.
|
||||
let "t = a<7?7:11" # True
|
||||
echo $t # 7
|
||||
|
||||
let a++
|
||||
let "t = a<7?7:11" # False
|
||||
echo $t # 11
|
||||
|
||||
exit
|
||||
|
|
|
@ -39,10 +39,12 @@ do
|
|||
done
|
||||
|
||||
return $number
|
||||
# Exercise:
|
||||
# --------
|
||||
# Explain how this function works.
|
||||
# Hint: division by successive subtraction.
|
||||
# Exercises:
|
||||
# ---------
|
||||
# 1) Explain how this function works.
|
||||
# Hint: division by successive subtraction.
|
||||
# 2) Extend to range of the function.
|
||||
# Hint: use "echo" and command-substitution capture.
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,7 +65,9 @@ num=$?
|
|||
to_roman $num 4 IV
|
||||
num=$?
|
||||
to_roman $num 1 I
|
||||
# Successive calls to conversion function!
|
||||
# Is this really necessary??? Can it be simplified?
|
||||
|
||||
echo
|
||||
|
||||
exit 0
|
||||
exit
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
# "and list"
|
||||
# and list
|
||||
|
||||
if [ ! -z "$1" ] && echo "Argument #1 = $1" && [ ! -z "$2" ] \
|
||||
&& echo "Argument #2 = $2"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
# delete.sh, not-so-cunning file deletion utility.
|
||||
# delete.sh, a not-so-cunning file deletion utility.
|
||||
# Usage: delete filename
|
||||
|
||||
E_BADARGS=65
|
||||
E_BADARGS=85
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
|
@ -25,4 +25,4 @@ Cowardly refusing to delete a nonexistent file."
|
|||
# Note logic inversion above.
|
||||
# AND LIST executes on true, OR LIST on false.
|
||||
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -27,6 +27,7 @@ index=0
|
|||
while [ "$index" -lt "$element_count" ]
|
||||
do # List all the elements in the array.
|
||||
echo ${colors[$index]}
|
||||
# ${colors[index]} also works because it's within ${ ... } brackets.
|
||||
let "index = $index + 1"
|
||||
# Or:
|
||||
# index+=1
|
||||
|
|
|
@ -21,7 +21,7 @@ Primes[i=1]='' # 1 is not a prime.
|
|||
until (( ( i += 1 ) > (${UPPER_LIMIT}/i) )) # Need check only ith-way.
|
||||
do # Why?
|
||||
if ((${Primes[t=i*(i-1), i]}))
|
||||
# Obscure, but instructive, use of numeric eval in subscript.
|
||||
# Obscure, but instructive, use of arithmetic expansion in subscript.
|
||||
then
|
||||
until (( ( t += i ) > ${UPPER_LIMIT} ))
|
||||
do Primes[t]=; done
|
||||
|
|
|
@ -45,6 +45,7 @@ echo "Creating swap file of size $blocks blocks (KB)."
|
|||
dd if=/dev/zero of=$FILE bs=$BLOCKSIZE count=$blocks # Zero out file.
|
||||
mkswap $FILE $blocks # Designate it a swap file.
|
||||
swapon $FILE # Activate swap file.
|
||||
retcode=$? # Everything worked?
|
||||
# Note that if one or more of these commands fails,
|
||||
#+ then it could cause nasty problems.
|
||||
######################################################################
|
||||
|
@ -59,4 +60,4 @@ swapon $FILE # Activate swap file.
|
|||
|
||||
echo "Swap file created and activated."
|
||||
|
||||
exit $SUCCESS
|
||||
exit $retcode
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
|
||||
echo $'Ringing bell 3 times \a \a \a'
|
||||
# May only ring once with certain terminals.
|
||||
# Or ...
|
||||
# May not ring at all, depending on terminal settings.
|
||||
echo $'Three form feeds \f \f \f'
|
||||
echo $'10 newlines \n\n\n\n\n\n\n\n\n\n'
|
||||
echo $'\102\141\163\150' # Bash
|
||||
# Octal equivalent of characters.
|
||||
# Octal equivalent of characters.
|
||||
|
||||
exit 0
|
||||
exit
|
||||
|
|
|
@ -26,3 +26,5 @@ echo "Value of t changed to ${!t}" # 387
|
|||
#+ would have been nice. Sigh.
|
||||
|
||||
exit 0
|
||||
|
||||
# See also, ind-ref.sh example.
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
# make sure /pipe really is a pipe and not a plain file
|
||||
rm -rf /pipe
|
||||
mkfifo /pipe # ==> Create a "named pipe", named "/pipe".
|
||||
mkfifo /pipe # ==> Create a "named pipe", named "/pipe" ...
|
||||
|
||||
# ==> 'su xyz' runs commands as user "xyz".
|
||||
# ==> 'ssh' invokes secure shell (remote login client).
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
# Two ways to count up to 10.
|
||||
# Multiple ways to count up to 10.
|
||||
|
||||
echo
|
||||
|
||||
|
@ -13,6 +13,27 @@ echo; echo
|
|||
|
||||
# +==========================================+
|
||||
|
||||
# Using "seq" ...
|
||||
for a in `seq 10`
|
||||
do
|
||||
echo -n "$a "
|
||||
done
|
||||
|
||||
echo; echo
|
||||
|
||||
# +==========================================+
|
||||
|
||||
# Using brace expansion ...
|
||||
# Bash, version 3+.
|
||||
for a in {1..10}
|
||||
do
|
||||
echo -n "$a "
|
||||
done
|
||||
|
||||
echo; echo
|
||||
|
||||
# +==========================================+
|
||||
|
||||
# Now, let's do the same, using C-like syntax.
|
||||
|
||||
LIMIT=10
|
||||
|
@ -28,8 +49,8 @@ echo; echo
|
|||
|
||||
# Let's use the C "comma operator" to increment two variables simultaneously.
|
||||
|
||||
for ((a=1, b=1; a <= LIMIT ; a++, b++)) # The comma chains together operations.
|
||||
do
|
||||
for ((a=1, b=1; a <= LIMIT ; a++, b++))
|
||||
do # The comma chains together operations.
|
||||
echo -n "$a-$b "
|
||||
done
|
||||
|
||||
|
|
|
@ -106,3 +106,6 @@ rm -f ${TMPFILE}
|
|||
# ==> ---------
|
||||
# ==> 1) Add error checking.
|
||||
# ==> 2) Add bells & whistles.
|
||||
|
||||
# See the included file "Moraes-COPYRIGHT" for copyright info.
|
||||
#+ on this script.
|
||||
|
|
|
@ -29,7 +29,7 @@ getopt_simple $*
|
|||
echo "test is '$test'"
|
||||
echo "test2 is '$test2'"
|
||||
|
||||
exit 0
|
||||
exit 0 # See also, UseGetOpt.sh, a modified versio of this script.
|
||||
|
||||
---
|
||||
|
||||
|
@ -42,3 +42,4 @@ Processing parameter of: '/test2=value2'
|
|||
Parameter: 'test2', value: 'value2'
|
||||
test is 'value1'
|
||||
test2 is 'value2'
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
# grp.sh: Very crude reimplementation of 'grep'.
|
||||
# grp.sh: Rudimentary reimplementation of grep.
|
||||
|
||||
E_BADARGS=65
|
||||
E_BADARGS=85
|
||||
|
||||
if [ -z "$1" ] # Check for argument to script.
|
||||
then
|
||||
|
@ -18,7 +18,7 @@ do
|
|||
if [ ! -z "$output" ] # What happens if "$output" is not quoted?
|
||||
then
|
||||
echo -n "$file: "
|
||||
echo $output
|
||||
echo "$output"
|
||||
fi # sed -ne "/$1/s|^|${file}: |p" is equivalent to above.
|
||||
|
||||
echo
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
#!/bin/bash
|
||||
# hexconvert.sh: Convert a decimal number to hexadecimal.
|
||||
|
||||
E_NOARGS=65 # Command-line arg missing.
|
||||
E_NOARGS=85 # Command-line arg missing.
|
||||
BASE=16 # Hexadecimal.
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
then # Need a command line argument.
|
||||
echo "Usage: $0 number"
|
||||
exit $E_NOARGS
|
||||
# Need a command line argument.
|
||||
fi
|
||||
# Exercise: add argument validity checking.
|
||||
fi # Exercise: add argument validity checking.
|
||||
|
||||
|
||||
hexcvt ()
|
||||
|
@ -22,12 +20,12 @@ then
|
|||
fi
|
||||
|
||||
echo ""$1" "$BASE" o p" | dc
|
||||
# "o" sets radix (numerical base) of output.
|
||||
# "p" prints the top of stack.
|
||||
# See 'man dc' for other options.
|
||||
# o sets radix (numerical base) of output.
|
||||
# p prints the top of stack.
|
||||
# For other options: 'man dc' ...
|
||||
return
|
||||
}
|
||||
|
||||
hexcvt "$1"
|
||||
|
||||
exit 0
|
||||
exit
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# License: Public Domain
|
||||
|
||||
# This script may be turned in to your instructor
|
||||
#+ in fulfillment of ALL Bash scripting homework assignments.
|
||||
#+ in fulfillment of ALL shell scripting homework assignments.
|
||||
# It's sparsely commented, but you, the student, can easily remedy that.
|
||||
# The script author repudiates all responsibility!
|
||||
|
||||
|
@ -73,14 +73,14 @@ b_r
|
|||
|
||||
for i in $(seq 0 $MAXL)
|
||||
do
|
||||
p_l "${L[i]}"
|
||||
if [[ "$i" -eq "$P1" || "$i" -eq "$P2" || "$i" -eq "$P3" ]]
|
||||
then
|
||||
cr
|
||||
elif [[ "$i" -eq "$PP1" || "$i" -eq "$PP2" ]]
|
||||
then
|
||||
cr; cr
|
||||
fi
|
||||
p_l "${L[i]}"
|
||||
if [[ "$i" -eq "$P1" || "$i" -eq "$P2" || "$i" -eq "$P3" ]]
|
||||
then
|
||||
cr
|
||||
elif [[ "$i" -eq "$PP1" || "$i" -eq "$PP2" ]]
|
||||
then
|
||||
cr; cr
|
||||
fi
|
||||
done
|
||||
|
||||
restore
|
||||
|
@ -90,6 +90,7 @@ echo
|
|||
|
||||
exit $E_LZY
|
||||
|
||||
# An example of an obfuscated script that is difficult to understand,
|
||||
#+ and frustrating to maintain.
|
||||
# In your career as a sysadmin, you'll run into these all too often.
|
||||
# A typical example of an obfuscated script that is difficult
|
||||
#+ to understand, and frustrating to maintain.
|
||||
# In your career as a sysadmin, you'll run into these critters
|
||||
#+ all too often.
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#!/bin/bash
|
||||
# ifs.sh
|
||||
|
||||
# $IFS treats whitespace differently than other characters.
|
||||
|
||||
output_args_one_per_line()
|
||||
|
|
|
@ -2,6 +2,27 @@
|
|||
# ind-ref.sh: Indirect variable referencing.
|
||||
# Accessing the contents of the contents of a variable.
|
||||
|
||||
# First, let's fool around a little.
|
||||
|
||||
var=23
|
||||
|
||||
echo "\$var = $var" # $var = 23
|
||||
# So far, everything as expected. But ...
|
||||
|
||||
echo "\$\$var = $$var" # $$var = 4570var
|
||||
# Not meaningful. The contents of a memory location pointed to?
|
||||
# Not useful at this point.
|
||||
|
||||
echo "\\\$\$var = \$$var" # \$$var = $23
|
||||
# As expected. The first $ is escaped and pasted on to
|
||||
#+ the value of var ($var = 23 ).
|
||||
# Meaningful, but still not useful.
|
||||
|
||||
# Now, let's start over and do it the right way.
|
||||
|
||||
# ============================================== #
|
||||
|
||||
|
||||
a=letter_of_alphabet # Variable "a" holds the name of another variable.
|
||||
letter_of_alphabet=z
|
||||
|
||||
|
@ -11,8 +32,14 @@ echo
|
|||
echo "a = $a" # a = letter_of_alphabet
|
||||
|
||||
# Indirect reference.
|
||||
eval a=\$$a
|
||||
echo "Now a = $a" # Now a = z
|
||||
eval a=\$$a
|
||||
# ^^^ Forcing an eval(uation), and ...
|
||||
# ^ Escaping the first $ ...
|
||||
# ------------------------------------------------------------------------
|
||||
# The 'eval' forces an update of $a, sets it to the updated value of \$$a.
|
||||
# So, we see why 'eval' so often shows up in indirect reference notation.
|
||||
# ------------------------------------------------------------------------
|
||||
echo "Now a = $a" # Now a = z
|
||||
|
||||
echo
|
||||
|
||||
|
@ -36,6 +63,7 @@ echo "\"table_cell_3\" now $table_cell_3"
|
|||
echo -n "dereferenced \"t\" now "; eval echo \$$t
|
||||
# "eval" takes the two arguments "echo" and "\$$t" (set equal to $table_cell_3)
|
||||
|
||||
|
||||
echo
|
||||
|
||||
# (Thanks, Stephane Chazelas, for clearing up the above behavior.)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
# int-or-string.sh: Integer or string?
|
||||
# int-or-string.sh
|
||||
|
||||
a=2334 # Integer.
|
||||
let "a += 1"
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
#!/bin/bash
|
||||
# life.sh: "Life in the Slow Lane"
|
||||
# Version 2: Patched by Daniel Albers
|
||||
#+ to allow non-square grids as input.
|
||||
# Version 0.2: Patched by Daniel Albers
|
||||
#+ to allow non-square grids as input.
|
||||
|
||||
# ##################################################################### #
|
||||
# This is the Bash script version of John Conway's "Game of Life". #
|
||||
# "Life" is a simple implementation of cellular automata. #
|
||||
# --------------------------------------------------------------------- #
|
||||
# On a rectangular grid, let each "cell" be either "living" or "dead". #
|
||||
# On a rectangular grid, let each "cell" be either "living" or "dead." #
|
||||
# Designate a living cell with a dot, and a dead one with a blank space.#
|
||||
# Begin with an arbitrarily drawn dot-and-blank grid, #
|
||||
#+ and let this be the starting generation, "generation 0." #
|
||||
# Determine each successive generation by the following rules: #
|
||||
# 1) Each cell has 8 neighbors, the adjoining cells #
|
||||
#+ left, right, top, bottom, and the 4 diagonals. #
|
||||
# 1) Each cell has 8 neighbors, the adjoining cells #
|
||||
#+ left, right, top, bottom, and the 4 diagonals. #
|
||||
# #
|
||||
# 123 #
|
||||
# 4*5 The * is the cell in question. #
|
||||
# 4*5 The * is the cell under consideration. #
|
||||
# 678 #
|
||||
# #
|
||||
# 2) A living cell with either 2 or 3 living neighbors remains alive. #
|
||||
SURVIVE=2 #
|
||||
# 3) A dead cell with 3 living neighbors becomes alive (a "birth"). #
|
||||
# 3) A dead cell with 3 living neighbors comes alive (a "birth"). #
|
||||
BIRTH=3 #
|
||||
# 4) All other cases result in a dead cell for the next generation. #
|
||||
# ##################################################################### #
|
||||
|
@ -38,7 +38,7 @@ fi
|
|||
############################################
|
||||
# Abort script if "startfile" not specified
|
||||
#+ and
|
||||
#+ "gen0" not present.
|
||||
#+ default file "gen0" not present.
|
||||
|
||||
E_NOSTARTFILE=68
|
||||
|
||||
|
@ -52,11 +52,11 @@ fi
|
|||
|
||||
ALIVE1=.
|
||||
DEAD1=_
|
||||
# Represent living and "dead" cells in the start-up file.
|
||||
# Represent living and dead cells in the start-up file.
|
||||
|
||||
# ---------------------------------------------------------- #
|
||||
# This script uses a 10 x 10 grid (may be increased,
|
||||
#+ but a large grid will will cause very slow execution).
|
||||
#+ but a large grid will slow execution).
|
||||
ROWS=10
|
||||
COLS=10
|
||||
# Change above two variables to match grid size, as desired.
|
||||
|
@ -66,7 +66,7 @@ GENERATIONS=10 # How many generations to cycle through.
|
|||
# Adjust this upwards,
|
||||
#+ if you have time on your hands.
|
||||
|
||||
NONE_ALIVE=80 # Exit status on premature bailout,
|
||||
NONE_ALIVE=85 # Exit status on premature bailout,
|
||||
#+ if no cells left alive.
|
||||
TRUE=0
|
||||
FALSE=1
|
||||
|
@ -78,17 +78,16 @@ generation=0 # Initialize generation count.
|
|||
|
||||
# =================================================================
|
||||
|
||||
let "cells = $ROWS * $COLS" # How many cells.
|
||||
|
||||
let "cells = $ROWS * $COLS"
|
||||
# How many cells.
|
||||
|
||||
declare -a initial # Arrays containing "cells."
|
||||
# Arrays containing "cells."
|
||||
declare -a initial
|
||||
declare -a current
|
||||
|
||||
display ()
|
||||
{
|
||||
|
||||
alive=0 # How many cells "alive" at any given time.
|
||||
alive=0 # How many cells alive at any given time.
|
||||
# Initially zero.
|
||||
|
||||
declare -a arr
|
||||
|
@ -161,13 +160,12 @@ return $TRUE # Valid coordinate.
|
|||
}
|
||||
|
||||
|
||||
IsAlive () # Test whether cell is alive.
|
||||
# Takes array, cell number, state of cell as arguments.
|
||||
{
|
||||
GetCount "$1" $2 # Get alive cell count in neighborhood.
|
||||
IsAlive () # Test whether cell is alive.
|
||||
# Takes array, cell number,
|
||||
{ #+ state of cell as arguments.
|
||||
GetCount "$1" $2 # Get alive cell count in neighborhood.
|
||||
local nhbd=$?
|
||||
|
||||
|
||||
if [ "$nhbd" -eq "$BIRTH" ] # Alive in any case.
|
||||
then
|
||||
return $ALIVE
|
||||
|
@ -178,7 +176,7 @@ IsAlive () # Test whether cell is alive.
|
|||
return $ALIVE
|
||||
fi
|
||||
|
||||
return $DEAD # Default.
|
||||
return $DEAD # Dead by default.
|
||||
|
||||
}
|
||||
|
||||
|
@ -216,7 +214,7 @@ GetCount () # Count live cells in passed cell's neighborhood.
|
|||
let "t_bot = $bottom + $i"
|
||||
|
||||
|
||||
let "row = $r" # Count center row of neighborhood.
|
||||
let "row = $r" # Count center row.
|
||||
IsValid $t_cen $row # Valid cell position?
|
||||
if [ $? -eq "$TRUE" ]
|
||||
then
|
||||
|
@ -280,7 +278,7 @@ do
|
|||
done
|
||||
|
||||
|
||||
# let "generation += 1" # Increment generation count.
|
||||
# let "generation += 1" # Increment generation count.
|
||||
# Why was the above line commented out?
|
||||
|
||||
|
||||
|
@ -293,7 +291,7 @@ echo "Generation $generation - $alive alive"
|
|||
if [ "$alive" -eq 0 ]
|
||||
then
|
||||
echo
|
||||
echo "Premature exit: no more cells alive!"
|
||||
echo "Unexpected exit: no more cells alive!"
|
||||
exit $NONE_ALIVE # No point in continuing
|
||||
fi #+ if no live cells.
|
||||
|
||||
|
@ -328,7 +326,7 @@ echo "Generation $generation - $alive alive"
|
|||
# -------------------------------------------
|
||||
|
||||
|
||||
let "generation += 1" # Increment generation count.
|
||||
let "generation += 1" # Bump generation count.
|
||||
echo
|
||||
|
||||
# ------- Display second generation. -------
|
||||
|
@ -349,7 +347,7 @@ done
|
|||
|
||||
echo
|
||||
|
||||
exit 0 # END
|
||||
exit 0 # CEOF:EOF
|
||||
|
||||
|
||||
|
||||
|
@ -371,5 +369,4 @@ exit 0 # END
|
|||
#+ in the script for an altered grid size.
|
||||
#
|
||||
# Exercise: Optimize this script.
|
||||
# It has some repetitive and redundant code,
|
||||
#+ for example, lines 335-336.
|
||||
# It has some redundant code.
|
||||
|
|
|
@ -47,4 +47,4 @@ sed "$sedscript" $1 | fold -s --width=$MAXWIDTH
|
|||
# An nice set of text processing utilities and an efficient
|
||||
#+ scripting language provide an alternative to bloated executables.
|
||||
|
||||
exit 0
|
||||
exit
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
#!/bin/bash
|
||||
# maned.sh
|
||||
# A rudimentary man page editor
|
||||
|
||||
# Version: 0.1 (Alpha, probably buggy)
|
||||
# Author: Mendel Cooper <thegrendel@theriver.com>
|
||||
# Reldate: 16 June 2008
|
||||
# License: GPL3
|
||||
|
||||
|
||||
savefile= # Global, used in multiple functions.
|
||||
E_NOINPUT=90 # User input missing (error). May or may not be critical.
|
||||
|
||||
# =========== Markup Tags ============ #
|
||||
TopHeader=".TH"
|
||||
NameHeader=".SH NAME"
|
||||
SyntaxHeader=".SH SYNTAX"
|
||||
SynopsisHeader=".SH SYNOPSIS"
|
||||
InstallationHeader=".SH INSTALLATION"
|
||||
DescHeader=".SH DESCRIPTION"
|
||||
OptHeader=".SH OPTIONS"
|
||||
FilesHeader=".SH FILES"
|
||||
EnvHeader=".SH ENVIRONMENT"
|
||||
AuthHeader=".SH AUTHOR"
|
||||
BugsHeader=".SH BUGS"
|
||||
SeeAlsoHeader=".SH SEE ALSO"
|
||||
BOLD=".B"
|
||||
# Add more tags, as needed.
|
||||
# See groff docs for markup meanings.
|
||||
# ==================================== #
|
||||
|
||||
start ()
|
||||
{
|
||||
clear # Clear screen.
|
||||
echo "ManEd"
|
||||
echo "-----"
|
||||
echo
|
||||
echo "Simple man page creator"
|
||||
echo "Author: Mendel Cooper"
|
||||
echo; echo; echo
|
||||
}
|
||||
|
||||
progname ()
|
||||
{
|
||||
echo -n "Program name? "
|
||||
read name
|
||||
|
||||
echo -n "Manpage section? [Hit RETURN for default (\"1\") ] "
|
||||
read section
|
||||
if [ -z "$section" ]
|
||||
then
|
||||
section=1 # Most man pages are in section 1.
|
||||
fi
|
||||
|
||||
if [ -n "$name" ]
|
||||
then
|
||||
savefile=""$name"."$section"" # Filename suffix = section.
|
||||
echo -n "$1 " >>$savefile
|
||||
name1=$(echo "$name" | tr a-z A-Z) # Change to uppercase,
|
||||
#+ per man page convention.
|
||||
echo -n "$name1" >>$savefile
|
||||
else
|
||||
echo "Error! No input." # Mandatory input.
|
||||
exit $E_NOINPUT # Critical!
|
||||
fi
|
||||
|
||||
echo -n " \"$section\"">>$savefile # Append, always append.
|
||||
|
||||
echo -n "Version? "
|
||||
read ver
|
||||
echo -n " \"Version $ver \"">>$savefile
|
||||
echo >>$savefile
|
||||
|
||||
echo -n "Short description [0 - 5 words]? "
|
||||
read sdesc
|
||||
echo "$NameHeader">>$savefile
|
||||
echo ""$BOLD" "$name"">>$savefile
|
||||
echo "\- "$sdesc"">>$savefile
|
||||
|
||||
}
|
||||
|
||||
fill_in ()
|
||||
{ # This function more or less copied from "pad.sh" script.
|
||||
echo -n "$2? " # Get user input.
|
||||
read var # May paste (a single line only!) to fill in field.
|
||||
|
||||
if [ -n "$var" ]
|
||||
then
|
||||
echo "$1 " >>$savefile
|
||||
echo -n "$var" >>$savefile
|
||||
else # Don't append empty field to file.
|
||||
return $E_NOINPUT # Not critical here.
|
||||
fi
|
||||
|
||||
echo >>$savefile
|
||||
|
||||
}
|
||||
|
||||
|
||||
end ()
|
||||
{
|
||||
clear
|
||||
echo -n "Would you like to view the saved man page (y/n)? "
|
||||
read ans
|
||||
if [ "$ans" = "n" -o "$ans" = "N" ]; then exit; fi
|
||||
exec less "$savefile" # Exit script and hand off control to "less" ...
|
||||
#+ ... which formats for viewing man page source.
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------- #
|
||||
start
|
||||
progname "$TopHeader"
|
||||
fill_in "$SynopsisHeader" "Synopsis"
|
||||
fill_in "$DescHeader" "Long description"
|
||||
# May paste in *single line* of text.
|
||||
fill_in "$OptHeader" "Options"
|
||||
fill_in "$FilesHeader" "Files"
|
||||
fill_in "$AuthHeader" "Author"
|
||||
fill_in "$BugsHeader" "Bugs"
|
||||
fill_in "$SeeAlsoHeader" "See also"
|
||||
# fill_in "$OtherHeader" ... as necessary.
|
||||
end # ... exit not needed.
|
||||
# ---------------------------------------- #
|
||||
|
||||
# Note that the generated man page will usually
|
||||
#+ require manual fine-tuning with a text editor.
|
||||
# However, it's a distinct improvement upon
|
||||
#+ writing man source from scratch
|
||||
#+ or even editing a blank man page template.
|
||||
|
||||
# The main deficiency of the script is that it permits
|
||||
#+ pasting only a single text line into the input fields.
|
||||
# This may be a long, cobbled-together line, which groff
|
||||
# will automatically wrap and hyphenate.
|
||||
# However, if you want multiple (newline-separated) paragraphs,
|
||||
#+ these must be inserted by manual text editing on the
|
||||
#+ script-generated man page.
|
||||
# Exercise (difficult): Fix this!
|
||||
|
||||
# This script is not nearly as elaborate as the
|
||||
#+ full-featured "manedit" package (http://wolfpack.twu.net),
|
||||
#+ but it's much easier to use.
|
|
@ -5,7 +5,7 @@
|
|||
# It lets you look at the intermediate results on the fly
|
||||
#+ while working on it.
|
||||
|
||||
E_WRONGARGS=65
|
||||
E_WRONGARGS=85
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
#!/bin/bash
|
||||
# match-string.sh: simple string matching
|
||||
# match-string.sh: Simple string matching.
|
||||
|
||||
match_string ()
|
||||
{
|
||||
{ # Exact string match.
|
||||
MATCH=0
|
||||
NOMATCH=90
|
||||
E_NOMATCH=90
|
||||
PARAMS=2 # Function requires 2 arguments.
|
||||
BAD_PARAMS=91
|
||||
E_BAD_PARAMS=91
|
||||
|
||||
[ $# -eq $PARAMS ] || return $BAD_PARAMS
|
||||
[ $# -eq $PARAMS ] || return $E_BAD_PARAMS
|
||||
|
||||
case "$1" in
|
||||
"$2") return $MATCH;;
|
||||
* ) return $NOMATCH;;
|
||||
* ) return $E_NOMATCH;;
|
||||
esac
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash
|
||||
# music.sh
|
||||
|
||||
# MUSIC WITHOUT EXTERNAL FILES
|
||||
|
||||
# Author: Antonio Macchi
|
||||
# Used in ABS Guide with permission
|
||||
|
||||
|
||||
# /dev/dsp default = 8000 frames per second, 8 bits per frame (1 byte),
|
||||
#+ 1 channel (mono)
|
||||
|
||||
duration=2000 # If 8000 bytes = 1 second, then 2000 = 1/4 second.
|
||||
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)
|
||||
{
|
||||
for t in `seq 0 $duration`
|
||||
do
|
||||
test $(( $t % $1 )) = 0 && echo -n $volume || echo -n $mute
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
e=`mknote 49`
|
||||
g=`mknote 41`
|
||||
a=`mknote 36`
|
||||
b=`mknote 32`
|
||||
c=`mknote 30`
|
||||
cis=`mknote 29`
|
||||
d=`mknote 27`
|
||||
e2=`mknote 24`
|
||||
n=`mknote 32767`
|
||||
# European notation.
|
||||
|
||||
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!
|
|
@ -13,7 +13,7 @@ Semmelweiss
|
|||
Smith
|
||||
Turing
|
||||
Venn
|
||||
Wilson
|
||||
Wilkinson
|
||||
Znosko-Borowski
|
||||
|
||||
# This is a data file for
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
#!/bin/bash
|
||||
# nim.sh: Game of Nim
|
||||
|
||||
# Author: Mendel Cooper
|
||||
# Reldate: 15 July 2008
|
||||
# License: GPL3
|
||||
|
||||
ROWS=5 # Five rows of pegs.
|
||||
WON=91 # Exit codes to keep track of wins/losses.
|
||||
LOST=92 # Possibly useful if running in batch mode.
|
||||
QUIT=99
|
||||
peg_msg= # Peg/Pegs?
|
||||
Rows=( 0 5 4 3 2 1 ) # Array holding play info.
|
||||
# ${Rows[0]} holds total number of pegs, updated after each turn.
|
||||
# Other array elements hold number of pegs in corresponding row.
|
||||
|
||||
instructions ()
|
||||
{
|
||||
clear
|
||||
tput bold
|
||||
echo "Welcome to the game of Nim."; echo
|
||||
echo -n "Do you need instructions? (y/n) "; read ans
|
||||
|
||||
if [ "$ans" = "y" -o "$ans" = "Y" ]; then
|
||||
clear
|
||||
echo -e '\E[33;41m' # Yellow fg., over red bg.; bold.
|
||||
cat <<INSTRUCTIONS
|
||||
|
||||
Nim is a game with roots in the distant past.
|
||||
This particular variant starts with five rows of pegs.
|
||||
|
||||
1: | | | | |
|
||||
2: | | | |
|
||||
3: | | |
|
||||
4: | |
|
||||
5: |
|
||||
|
||||
The number at the left identifies the row.
|
||||
|
||||
The human player moves first, and alternates turns with the bot.
|
||||
A turn consists of removing at least one peg from a single row.
|
||||
It is permissable to remove ALL the pegs from a row.
|
||||
For example, in row 2, above, the player can remove 1, 2, 3, or 4 pegs.
|
||||
The player who removes the last peg loses.
|
||||
|
||||
The strategy consists of trying to be the one who removes
|
||||
the next-to-last peg(s), leaving the loser with the final peg.
|
||||
|
||||
To exit the game early, hit ENTER during your turn.
|
||||
INSTRUCTIONS
|
||||
|
||||
echo; echo -n "Hit ENTER to begin game. "; read azx
|
||||
|
||||
echo -e "\033[0m" # Restore display.
|
||||
else tput sgr0; clear
|
||||
fi
|
||||
|
||||
clear
|
||||
|
||||
}
|
||||
|
||||
|
||||
tally_up ()
|
||||
{
|
||||
let "Rows[0] = ${Rows[1]} + ${Rows[2]} + ${Rows[3]} + ${Rows[4]} + \
|
||||
${Rows[5]}" # Add up how many pegs remaining.
|
||||
}
|
||||
|
||||
|
||||
display ()
|
||||
{
|
||||
index=1 # Start with top row.
|
||||
echo
|
||||
|
||||
while [ "$index" -le "$ROWS" ]
|
||||
do
|
||||
p=${Rows[index]}
|
||||
echo -n "$index: " # Show row number.
|
||||
|
||||
# ------------------------------------------------
|
||||
# Two concurrent inner loops.
|
||||
|
||||
indent=$index
|
||||
while [ "$indent" -gt 0 ]
|
||||
do
|
||||
echo -n " " # Staggered rows.
|
||||
((indent--)) # Spacing between pegs.
|
||||
done
|
||||
|
||||
while [ "$p" -gt 0 ]
|
||||
do
|
||||
echo -n "| "
|
||||
((p--))
|
||||
done
|
||||
# -----------------------------------------------
|
||||
|
||||
echo
|
||||
((index++))
|
||||
done
|
||||
|
||||
tally_up
|
||||
|
||||
rp=${Rows[0]}
|
||||
|
||||
if [ "$rp" -eq 1 ]
|
||||
then
|
||||
peg_msg=peg
|
||||
final_msg="Game over."
|
||||
else # Game not yet over . . .
|
||||
peg_msg=pegs
|
||||
final_msg="" # . . . So "final message" is blank.
|
||||
fi
|
||||
|
||||
echo " $rp $peg_msg remaining."
|
||||
echo " "$final_msg""
|
||||
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
player_move ()
|
||||
{
|
||||
|
||||
echo "Your move:"
|
||||
|
||||
echo -n "Which row? "
|
||||
while read idx
|
||||
do # Validity check, etc.
|
||||
|
||||
if [ -z "$idx" ] # Hitting return quits.
|
||||
then
|
||||
echo "Premature exit."; echo
|
||||
tput sgr0 # Restore display.
|
||||
exit $QUIT
|
||||
fi
|
||||
|
||||
if [ "$idx" -gt "$ROWS" -o "$idx" -lt 1 ] # Bounds check.
|
||||
then
|
||||
echo "Invalid row number!"
|
||||
echo -n "Which row? "
|
||||
else
|
||||
break
|
||||
fi
|
||||
# TODO:
|
||||
# Add check for non-numeric input.
|
||||
# Also, script crashes on input outside of range of long double.
|
||||
# Fix this.
|
||||
|
||||
done
|
||||
|
||||
echo -n "Remove how many? "
|
||||
while read num
|
||||
do # Validity check.
|
||||
|
||||
if [ -z "$num" ]
|
||||
then
|
||||
echo "Premature exit."; echo
|
||||
tput sgr0 # Restore display.
|
||||
exit $QUIT
|
||||
fi
|
||||
|
||||
if [ "$num" -gt ${Rows[idx]} -o "$num" -lt 1 ]
|
||||
then
|
||||
echo "Cannot remove $num!"
|
||||
echo -n "Remove how many? "
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
# TODO:
|
||||
# Add check for non-numeric input.
|
||||
# Also, script crashes on input outside of range of long double.
|
||||
# Fix this.
|
||||
|
||||
let "Rows[idx] -= $num"
|
||||
|
||||
display
|
||||
tally_up
|
||||
|
||||
if [ ${Rows[0]} -eq 1 ]
|
||||
then
|
||||
echo " Human wins!"
|
||||
echo " Congratulations!"
|
||||
tput sgr0 # Restore display.
|
||||
echo
|
||||
exit $WON
|
||||
fi
|
||||
|
||||
if [ ${Rows[0]} -eq 0 ]
|
||||
then # Snatching defeat from the jaws of victory . . .
|
||||
echo " Fool!"
|
||||
echo " You just removed the last peg!"
|
||||
echo " Bot wins!"
|
||||
tput sgr0 # Restore display.
|
||||
echo
|
||||
exit $LOST
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
bot_move ()
|
||||
{
|
||||
|
||||
row_b=0
|
||||
while [[ $row_b -eq 0 || ${Rows[row_b]} -eq 0 ]]
|
||||
do
|
||||
row_b=$RANDOM # Choose random row.
|
||||
let "row_b %= $ROWS"
|
||||
done
|
||||
|
||||
|
||||
num_b=0
|
||||
r0=${Rows[row_b]}
|
||||
|
||||
if [ "$r0" -eq 1 ]
|
||||
then
|
||||
num_b=1
|
||||
else
|
||||
let "num_b = $r0 - 1"
|
||||
# Leave only a single peg in the row.
|
||||
fi # Not a very strong strategy,
|
||||
#+ but probably a bit better than totally random.
|
||||
|
||||
let "Rows[row_b] -= $num_b"
|
||||
echo -n "Bot: "
|
||||
echo "Removing from row $row_b ... "
|
||||
|
||||
if [ "$num_b" -eq 1 ]
|
||||
then
|
||||
peg_msg=peg
|
||||
else
|
||||
peg_msg=pegs
|
||||
fi
|
||||
|
||||
echo " $num_b $peg_msg."
|
||||
|
||||
display
|
||||
tally_up
|
||||
|
||||
if [ ${Rows[0]} -eq 1 ]
|
||||
then
|
||||
echo " Bot wins!"
|
||||
tput sgr0 # Restore display.
|
||||
exit $WON
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
# ================================================== #
|
||||
instructions # If human player needs them . . .
|
||||
tput bold # Bold characters for easier viewing.
|
||||
display # Show game board.
|
||||
|
||||
while [ true ] # Main loop.
|
||||
do # Alternate human and bot turns.
|
||||
player_move
|
||||
bot_move
|
||||
done
|
||||
# ================================================== #
|
||||
|
||||
# Exercise:
|
||||
# --------
|
||||
# Improve the bot's strategy.
|
||||
# There is, in fact, a Nim strategy that can force a win.
|
||||
# See the Wikipedia article on Nim: http://en.wikipedia.org/wiki/Nim
|
||||
# Recode the bot to use this strategy (rather difficult).
|
||||
|
||||
# Curiosities:
|
||||
# -----------
|
||||
# Nim played a prominent role in Alain Resnais' 1961 New Wave film,
|
||||
#+ Last Year at Marienbad.
|
||||
#
|
||||
# In 1978, Leo Christopherson wrote an animated version of Nim,
|
||||
#+ Android Nim, for the TRS-80 Model I.
|
|
@ -57,4 +57,8 @@ let "bad_oct = 081"
|
|||
# bad_oct = 081: value too great for base (error token is "081")
|
||||
# Octal numbers use only digits in the range 0 - 7.
|
||||
|
||||
exit 0 # Thanks, Rich Bartell and Stephane Chazelas, for clarification.
|
||||
exit $? # Thanks, Rich Bartell and Stephane Chazelas, for clarification.
|
||||
|
||||
$ sh numbers.sh
|
||||
$ echo $?
|
||||
$ 1
|
||||
|
|
|
@ -15,6 +15,8 @@ Attrib[2]="\"Thirteen Ways of Looking at a Blackbird\""
|
|||
|
||||
echo
|
||||
|
||||
tput bold # Bold print.
|
||||
|
||||
for index in 1 2 3 4 5 # Five lines.
|
||||
do
|
||||
printf " %s\n" "${Line[index]}"
|
||||
|
@ -25,6 +27,9 @@ do
|
|||
printf " %s\n" "${Attrib[index]}"
|
||||
done
|
||||
|
||||
tput sgr0 # Reset terminal.
|
||||
# See 'tput' docs.
|
||||
|
||||
echo
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# pr-ascii.sh: Prints a table of ASCII characters.
|
||||
|
||||
START=33 # Range of printable ASCII characters (decimal).
|
||||
END=125
|
||||
END=127 # Will not work for unprintable chars. (> 127).
|
||||
|
||||
echo " Decimal Hex Character" # Header.
|
||||
echo " ------- --- ---------"
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/bash
|
||||
# primes2.sh
|
||||
|
||||
# Generating prime numbers the quick-and-easy way,
|
||||
#+ without resorting to fancy algorithms.
|
||||
|
||||
CEILING=10000 # 1 to 10000
|
||||
PRIME=0
|
||||
E_NOTPRIME=
|
||||
|
||||
is_prime ()
|
||||
{
|
||||
local factors
|
||||
factors=( $(factor $1) ) # Load output of `factor` into array.
|
||||
|
||||
if [ -z "${factors[2]}" ]
|
||||
# Third element of "factors" array:
|
||||
#+ ${factors[2]} is 2nd factor of argument.
|
||||
# If it is blank, then there is no 2nd factor,
|
||||
#+ and the argument is therefore prime.
|
||||
then
|
||||
return $PRIME # 0
|
||||
else
|
||||
return $E_NOTPRIME # null
|
||||
fi
|
||||
}
|
||||
|
||||
echo
|
||||
for n in $(seq $CEILING)
|
||||
do
|
||||
if is_prime $n
|
||||
then
|
||||
printf %5d $n
|
||||
fi # ^ Five positions per number suffices.
|
||||
done # For a higher $CEILING, adjust upward, as necessary.
|
||||
|
||||
echo
|
||||
|
||||
exit
|
|
@ -0,0 +1,52 @@
|
|||
#!/bin/bash
|
||||
# progress-bar.sh
|
||||
|
||||
# Author: Dotan Barak (very minor revisions by ABS Guide author).
|
||||
# Used in ABS Guide with permission (thanks!).
|
||||
|
||||
|
||||
BAR_WIDTH=50
|
||||
BAR_CHAR_START="["
|
||||
BAR_CHAR_END="]"
|
||||
BAR_CHAR_EMPTY="."
|
||||
BAR_CHAR_FULL="="
|
||||
BRACKET_CHARS=2
|
||||
LIMIT=100
|
||||
|
||||
print_progress_bar()
|
||||
{
|
||||
# Calculate how many characters will be full.
|
||||
let "full_limit = ((($1 - $BRACKET_CHARS) * $2) / $LIMIT)"
|
||||
|
||||
# Calculate how many characters will be empty.
|
||||
let "empty_limit = ($1 - $BRACKET_CHARS) - ${full_limit}"
|
||||
|
||||
# Prepare the bar.
|
||||
bar_line="${BAR_CHAR_START}"
|
||||
for ((j=0; j<full_limit; j++)); do
|
||||
bar_line="${bar_line}${BAR_CHAR_FULL}"
|
||||
done
|
||||
|
||||
for ((j=0; j<empty_limit; j++)); do
|
||||
bar_line="${bar_line}${BAR_CHAR_EMPTY}"
|
||||
done
|
||||
|
||||
bar_line="${bar_line}${BAR_CHAR_END}"
|
||||
|
||||
printf "%3d%% %s" $2 ${bar_line}
|
||||
}
|
||||
|
||||
# Here is a sample of code that uses it.
|
||||
MAX_PERCENT=100
|
||||
for ((i=0; i<=MAX_PERCENT; i++)); do
|
||||
#
|
||||
usleep 10000
|
||||
# ... Or run some other commands ...
|
||||
#
|
||||
print_progress_bar ${BAR_WIDTH} ${i}
|
||||
echo -en "\r"
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
exit
|
|
@ -25,7 +25,7 @@ echo "Q-series [$LIMIT terms]:"
|
|||
echo -n "${Q[1]} " # Output first two terms.
|
||||
echo -n "${Q[2]} "
|
||||
|
||||
for ((n=3; n <= $LIMIT; n++)) # C-like loop expressions.
|
||||
for ((n=3; n <= $LIMIT; n++)) # C-like loop expression.
|
||||
do # Q[n] = Q[n - Q[n-1]] + Q[n - Q[n-2]] for n>2
|
||||
# Need to break the expression into intermediate terms,
|
||||
#+ since Bash doesn't handle complex array arithmetic very well.
|
||||
|
@ -56,4 +56,4 @@ exit 0
|
|||
# This is an iterative implementation of the Q-series.
|
||||
# The more intuitive recursive implementation is left as an exercise.
|
||||
# Warning: calculating this series recursively takes a VERY long time
|
||||
#+ via a script. C/C++ would be more suitable.
|
||||
#+ via a script. C/C++ would be orders of magnitude faster.
|
||||
|
|
|
@ -460,3 +460,6 @@ exit $?
|
|||
# 5) Implement "vulnerable" mode of play.
|
||||
# 6) Improve save-to-file capability (and maybe make it optional).
|
||||
# 7) Fix bugs!!!
|
||||
|
||||
# Reference for more info:
|
||||
# http://personal.riverusers.com/~thegrendel/qky.README.html
|
||||
|
|
|
@ -16,12 +16,13 @@ then
|
|||
exit $E_WRONGARGS
|
||||
fi
|
||||
|
||||
file_excerpt () # Scan file for pattern, then print relevant portion of line.
|
||||
{
|
||||
while read line # "while" does not necessarily need "[ condition ]"
|
||||
do
|
||||
echo "$line" | grep $1 | awk -F":" '{ print $5 }' # Have awk use ":" delimiter.
|
||||
done
|
||||
file_excerpt () # Scan file for pattern,
|
||||
{ #+ then print relevant portion of line.
|
||||
while read line # "while" does not necessarily need [ condition ]
|
||||
do
|
||||
echo "$line" | grep $1 | awk -F":" '{ print $5 }'
|
||||
# Have awk use ":" delimiter.
|
||||
done
|
||||
} <$file # Redirect into function's stdin.
|
||||
|
||||
file_excerpt $pattern
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
# resistor-inventory.sh
|
||||
# Simple database application using indirect variable referencing.
|
||||
# Simple database / table-lookup application.
|
||||
|
||||
# ============================================================== #
|
||||
# Data
|
||||
|
@ -18,7 +18,7 @@ B1724_loc=24N
|
|||
B1724_inventory=243
|
||||
|
||||
B1725_value=10000
|
||||
B1725_powerdissip=.25
|
||||
B1725_powerdissip=.125
|
||||
B1725_colorcode="brown-black-orange"
|
||||
B1725_loc=24N
|
||||
B1725_inventory=89
|
||||
|
@ -42,7 +42,9 @@ do
|
|||
|
||||
echo
|
||||
echo "Catalog number $catalog_number:"
|
||||
echo "There are ${!Inv} of [${!Val} ohm / ${!Pdissip} watt] resistors in stock."
|
||||
# Now, retrieve value, using indirect referencing.
|
||||
echo "There are ${!Inv} of [${!Val} ohm / ${!Pdissip} watt]\
|
||||
resistors in stock." # ^ ^
|
||||
echo "These are located in bin # ${!Loc}."
|
||||
echo "Their color code is \"${!Ccode}\"."
|
||||
|
||||
|
@ -57,6 +59,7 @@ echo; echo
|
|||
# 2) Rewrite this script to use arrays,
|
||||
#+ rather than indirect variable referencing.
|
||||
# Which method is more straightforward and intuitive?
|
||||
# Which method is easier to code?
|
||||
|
||||
|
||||
# Notes:
|
||||
|
|
|
@ -14,6 +14,7 @@ for element in $(seq 0 $((${#script_contents[@]} - 1)))
|
|||
# Try changing it to seq 1.
|
||||
echo -n "${script_contents[$element]}"
|
||||
# List each field of this script on a single line.
|
||||
# echo -n "${script_contents[element]}" also works because of ${ ... }.
|
||||
echo -n " -- " # Use " -- " as a field separator.
|
||||
done
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
#!/bin/bash
|
||||
# sd.sh: Standard Deviation
|
||||
|
||||
# The Standard Deviation indicates how consistent a set of data is.
|
||||
# It shows to what extent the individual data points deviate from the
|
||||
#+ arithmetic mean, i.e., how much they "bounce around" (or cluster).
|
||||
# It is essentially the average deviation-distance of the
|
||||
#+ data points from the mean.
|
||||
|
||||
# =========================================================== #
|
||||
# To calculate the Standard Deviation:
|
||||
#
|
||||
# 1 Find the arithmetic mean (average) of all the data points.
|
||||
# 2 Subtract each data point from the arithmetic mean,
|
||||
# and square that difference.
|
||||
# 3 Add all of the individual difference-squares in # 2.
|
||||
# 4 Divide the sum in # 3 by the number of data points.
|
||||
# This is known as the "variance."
|
||||
# 5 The square root of # 4 gives the Standard Deviation.
|
||||
# =========================================================== #
|
||||
|
||||
count=0 # Number of data points; global.
|
||||
SC=9 # Scale to be used by bc. Nine decimal places.
|
||||
E_DATAFILE=90 # Data file error.
|
||||
|
||||
# ----------------- Set data file ---------------------
|
||||
if [ ! -z $1 ] # Specify filename as cmd-line arg?
|
||||
then
|
||||
datafile="$1" # ASCII text file,
|
||||
else #+ one (numerical) data point per line!
|
||||
datafile=sample.dat
|
||||
fi # See example data file, below.
|
||||
|
||||
if [ ! -e "$datafile" ]
|
||||
then
|
||||
echo "\""$datafile"\" does not exist!"
|
||||
exit $E_DATAFILE
|
||||
fi
|
||||
# -----------------------------------------------------
|
||||
|
||||
|
||||
arith_mean ()
|
||||
{
|
||||
local rt=0 # Running total.
|
||||
local am=0 # Arithmetic mean.
|
||||
local ct=0 # Number of data points.
|
||||
|
||||
while read value # Read one data point at a time.
|
||||
do
|
||||
rt=$(echo "scale=$SC; $rt + $value" | bc)
|
||||
(( ct++ ))
|
||||
done
|
||||
|
||||
am=$(echo "scale=$SC; $rt / $ct" | bc)
|
||||
|
||||
echo $am; return $ct # This function "returns" TWO values!
|
||||
# Caution: This little trick will not work if $ct > 255!
|
||||
# To handle a larger number of data points,
|
||||
#+ simply comment out the "return $ct" above.
|
||||
} <"$datafile" # Feed in data file.
|
||||
|
||||
sd ()
|
||||
{
|
||||
mean1=$1 # Arithmetic mean (passed to function).
|
||||
n=$2 # How many data points.
|
||||
sum2=0 # Sum of squared differences ("variance").
|
||||
avg2=0 # Average of $sum2.
|
||||
sdev=0 # Standard Deviation.
|
||||
|
||||
while read value # Read one line at a time.
|
||||
do
|
||||
diff=$(echo "scale=$SC; $mean1 - $value" | bc)
|
||||
# Difference between arith. mean and data point.
|
||||
dif2=$(echo "scale=$SC; $diff * $diff" | bc) # Squared.
|
||||
sum2=$(echo "scale=$SC; $sum2 + $dif2" | bc) # Sum of squares.
|
||||
done
|
||||
|
||||
avg2=$(echo "scale=$SC; $sum2 / $n" | bc) # Avg. of sum of squares.
|
||||
sdev=$(echo "scale=$SC; sqrt($avg2)" | bc) # Square root =
|
||||
echo $sdev # Standard Deviation.
|
||||
|
||||
} <"$datafile" # Rewinds data file.
|
||||
|
||||
|
||||
# ======================================================= #
|
||||
mean=$(arith_mean); count=$? # Two returns from function!
|
||||
std_dev=$(sd $mean $count)
|
||||
|
||||
echo
|
||||
echo "Number of data points in \""$datafile"\" = $count"
|
||||
echo "Arithmetic mean (average) = $mean"
|
||||
echo "Standard Deviation = $std_dev"
|
||||
echo
|
||||
# ======================================================= #
|
||||
|
||||
exit
|
||||
|
||||
# This script could stand some drastic streamlining,
|
||||
# but not at the cost of reduced legibility, please.
|
||||
|
||||
|
||||
# ++++++++++++++++++++++++++++++++++++++++ #
|
||||
# A sample data file (sample1.dat):
|
||||
|
||||
# 18.35
|
||||
# 19.0
|
||||
# 18.88
|
||||
# 18.91
|
||||
# 18.64
|
||||
|
||||
|
||||
# $ sh sd.sh sample1.dat
|
||||
|
||||
# Number of data points in "sample1.dat" = 5
|
||||
# Arithmetic mean (average) = 18.756000000
|
||||
# Standard Deviation = .235338054
|
||||
# ++++++++++++++++++++++++++++++++++++++++ #
|
|
@ -4,24 +4,20 @@
|
|||
|
||||
# Using if [ ... ]
|
||||
|
||||
|
||||
# If a string has not been initialized, it has no defined value.
|
||||
# This state is called "null" (not the same as zero).
|
||||
# This state is called "null" (not the same as zero!).
|
||||
|
||||
if [ -n $string1 ] # $string1 has not been declared or initialized.
|
||||
if [ -n $string1 ] # string1 has not been declared or initialized.
|
||||
then
|
||||
echo "String \"string1\" is not null."
|
||||
else
|
||||
echo "String \"string1\" is null."
|
||||
fi
|
||||
# Wrong result.
|
||||
fi # Wrong result.
|
||||
# Shows $string1 as not null, although it was not initialized.
|
||||
|
||||
|
||||
echo
|
||||
|
||||
|
||||
# Lets try it again.
|
||||
# Let's try it again.
|
||||
|
||||
if [ -n "$string1" ] # This time, $string1 is quoted.
|
||||
then
|
||||
|
@ -30,51 +26,43 @@ else
|
|||
echo "String \"string1\" is null."
|
||||
fi # Quote strings within test brackets!
|
||||
|
||||
|
||||
echo
|
||||
|
||||
|
||||
if [ $string1 ] # This time, $string1 stands naked.
|
||||
then
|
||||
echo "String \"string1\" is not null."
|
||||
else
|
||||
echo "String \"string1\" is null."
|
||||
fi
|
||||
# This works fine.
|
||||
# The [ ] test operator alone detects whether the string is null.
|
||||
# However it is good practice to quote it ("$string1").
|
||||
fi # This works fine.
|
||||
# The [ ... ] test operator alone detects whether the string is null.
|
||||
# However it is good practice to quote it (if [ "$string1" ]).
|
||||
#
|
||||
# As Stephane Chazelas points out,
|
||||
# if [ $string1 ] has one argument, "]"
|
||||
# if [ "$string1" ] has two arguments, the empty "$string1" and "]"
|
||||
|
||||
|
||||
|
||||
echo
|
||||
|
||||
|
||||
|
||||
string1=initialized
|
||||
|
||||
if [ $string1 ] # Again, $string1 stands naked.
|
||||
if [ $string1 ] # Again, $string1 stands unquoted.
|
||||
then
|
||||
echo "String \"string1\" is not null."
|
||||
else
|
||||
echo "String \"string1\" is null."
|
||||
fi
|
||||
# Again, gives correct result.
|
||||
fi # Again, gives correct result.
|
||||
# Still, it is better to quote it ("$string1"), because . . .
|
||||
|
||||
|
||||
string1="a = b"
|
||||
|
||||
if [ $string1 ] # Again, $string1 stands naked.
|
||||
if [ $string1 ] # Again, $string1 stands unquoted.
|
||||
then
|
||||
echo "String \"string1\" is not null."
|
||||
else
|
||||
echo "String \"string1\" is null."
|
||||
fi
|
||||
# Not quoting "$string1" now gives wrong result!
|
||||
fi # Not quoting "$string1" now gives wrong result!
|
||||
|
||||
exit 0
|
||||
# Thank you, also, Florian Wisser, for the "heads-up".
|
||||
exit 0 # Thank you, also, Florian Wisser, for the "heads-up".
|
||||
|
|
|
@ -5,8 +5,8 @@ String=23skidoo1
|
|||
# 012345678 Bash
|
||||
# 123456789 awk
|
||||
# Note different string indexing system:
|
||||
# Bash numbers first character of string as '0'.
|
||||
# Awk numbers first character of string as '1'.
|
||||
# Bash numbers first character of string as 0.
|
||||
# Awk numbers first character of string as 1.
|
||||
|
||||
echo ${String:2:4} # position 3 (0-1-2), 4 characters long
|
||||
# skid
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
# tohtml.sh
|
||||
# tohtml.sh [v. 0.2, reldate: 06/26/80, still buggy]
|
||||
|
||||
# Convert a text file to HTML format.
|
||||
# Author: Mendel Cooper
|
||||
|
@ -96,10 +96,10 @@ process_text ()
|
|||
# ===================================================
|
||||
# Convert underscored phrase to italics.
|
||||
temp=$( echo "$line" |
|
||||
sed -e 's/ _/ <i>/' -e 's/_ /<\/i> /' |
|
||||
sed -e 's/^_/<i>/' -e 's/_$/<\/i>/' )
|
||||
sed -e 's/ _/ <i>/' -e 's/_/<\/i> /' |
|
||||
sed -e 's/^_/<i>/' -e 's/_/<\/i>/' )
|
||||
# Process only underscores prefixed by space,
|
||||
#+ followed by space, or at beginning or end of line.
|
||||
#+ or at beginning or end of line.
|
||||
# Do not convert underscores embedded within a word!
|
||||
line="$temp"
|
||||
# Slows script execution. Can be optimized?
|
||||
|
|
|
@ -5,17 +5,17 @@ trap 'echo "VARIABLE-TRACE> \$variable = \"$variable\""' DEBUG
|
|||
|
||||
variable=29
|
||||
|
||||
echo "Just initialized \"\$variable\" to $variable."
|
||||
echo " Just initialized \$variable to $variable."
|
||||
|
||||
let "variable *= 3"
|
||||
echo "Just multiplied \"\$variable\" by 3."
|
||||
echo " Just multiplied \$variable by 3."
|
||||
|
||||
exit $?
|
||||
exit
|
||||
|
||||
# The "trap 'command1 . . . command2 . . .' DEBUG" construct is
|
||||
#+ more appropriate in the context of a complex script,
|
||||
#+ where placing multiple "echo $variable" statements might be
|
||||
#+ clumsy and time-consuming.
|
||||
#+ where inserting multiple "echo $variable" statements might be
|
||||
#+ awkward and time-consuming.
|
||||
|
||||
# Thanks, Stephane Chazelas for the pointer.
|
||||
|
||||
|
@ -24,8 +24,8 @@ Output of script:
|
|||
|
||||
VARIABLE-TRACE> $variable = ""
|
||||
VARIABLE-TRACE> $variable = "29"
|
||||
Just initialized "$variable" to 29.
|
||||
Just initialized $variable to 29.
|
||||
VARIABLE-TRACE> $variable = "29"
|
||||
VARIABLE-TRACE> $variable = "87"
|
||||
Just multiplied "$variable" by 3.
|
||||
Just multiplied $variable by 3.
|
||||
VARIABLE-TRACE> $variable = "87"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
E_WRONG_DIRECTORY=73
|
||||
E_WRONG_DIRECTORY=83
|
||||
|
||||
clear # Clear screen.
|
||||
|
||||
|
@ -23,15 +23,16 @@ rm .[A-Za-z0-9]* # Delete dotfiles.
|
|||
# (shopt -s dotglob; rm -f *) will also work.
|
||||
# Thanks, S.C. for pointing this out.
|
||||
|
||||
# Filenames may contain all characters in the 0 - 255 range, except "/".
|
||||
# Deleting files beginning with weird characters is left as an exercise.
|
||||
|
||||
# Various other operations here, as necessary.
|
||||
# A filename (`basename`) may contain all characters in the 0 - 255 range,
|
||||
#+ except "/".
|
||||
# Deleting files beginning with weird characters, such as -
|
||||
#+ is left as an exercise.
|
||||
|
||||
echo
|
||||
echo "Done."
|
||||
echo "Old files deleted in $TargetDirectory."
|
||||
echo
|
||||
|
||||
# Various other operations here, as necessary.
|
||||
|
||||
exit 0
|
||||
exit $?
|
||||
|
|
|
@ -28,9 +28,10 @@ fi
|
|||
|
||||
MINSTRLEN=3 # Minimum string length.
|
||||
WORDFILE=/usr/share/dict/linux.words # Dictionary file.
|
||||
# May specify a different
|
||||
#+ word list file
|
||||
#+ of one-word-per-line format.
|
||||
# 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
|
||||
|
||||
|
||||
wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \
|
||||
|
|
Loading…
Reference in New Issue