This commit is contained in:
gferg 2011-08-29 23:59:19 +00:00
parent c5a622cb65
commit 189f9f596e
43 changed files with 1179 additions and 363 deletions

View File

@ -3,19 +3,108 @@
Release History Release History
The latest version of this file is available on-line at The latest version of this file is available on-line at
http://http://bash.neuralshortcircuit.com/Change.log http://http://bash.webofcrafts.net/Change.log
================================================================== ==================================================================
Current version = 6.3 Current version = 6.4
Dated 04/30/12 Dated 08/30/11
http://bash.webofcrafts.net/abs-guide-latest.tar.bz2 http://bash.webofcrafts.net/abs-guide-latest.tar.bz2
http://bash.webofcrafts.net/abs-guide.pdf http://bash.webofcrafts.net/abs-guide.pdf
-------------------------------------------------------------------- --------------------------------------------------------------------
News: Version 6.3 released! News: Version 6.4 released!
==================================================================== ====================================================================
Version 6.4, Vortexberry* release
30 August 2011
1) In "Shell Programming!" chapter:
Fixed format of block-quote on the BASIC language.
2) In the "Tests" chapter:
Added a warning about whitespace in
if [ "$a" = "b" ] test construct.
Added a caution about the exit status of an arithmetic expression.
(Thanks, ujqm8360, for the pointer.)
3) In "Variables Revisited" chapter:
In "Manipulating Strings" section:
In the first substring removal example, added instances of
parameterization.
4) In "Testing and Branching" section of "Loops and Branches" chapter:
Added footnote concerning optional left-paren in "case" statements.
(Thank you, "amphiboly" and Jens Schweikhardt.)
5) In "Miscellany" chapter,
In "Shell Scripting Under Windows" section,
noted MSFT release of Windows PowerShell.
6) In "I/O Redirection" chapter:
Added non-standard "input-file command > output-file"
to opening examples.
(Thank you, "amphiboly" and Jens Schweikhardt.)
7) In "Functions" chapter:
Added a "single-command" instance to note about "compacted" functions.
Added entry to "_()" example concerning ":()" function name.
In "empty function" example, noted that a function containing
only comments is still empty. (Thank you, Mark Bova.)
8) In "Bash, versions 2, 3, and 4" chapter:
In "Bash, version 4" section,
At "associative array" entry, added caution that index array
elements containing only whitespace are not permitted.
9) In "Local Variables" section of "Functions" chapter:
Added footnote concerning visibility of local variables
in daughter functions.
(Thank you, Thomas Braunberger.)
10) In "Here Strings" section of "Here Documents" chapter:
Added an example of feeding the stdin of a loop from a here string.
(Thank you, Seamus.)
11) In "Process Substitution" chapter:
Added Bill Davidsen's example (Thanks!).
12) In "External Commands" chapter:
In "Text Processing" section:
At "tr" entry, added "Just another Bash hacker!" example script.
snippet (courtesy of a Wikipedia article).
In "Math Commands" section:
At "dc" entry, elaborated first example and added one line
of explanation.
13) In "Debugging" chapter:
At "trap" entry, added Graham Ewart's "progress bar" script.
(Thanks!)
At "set -u" entry, correction and example snippet added.
14) In "Bash, versions 2, 3, and 4" chapter,
In the Version 3.1 section,
Corrected the "+=" entry (Thanks, Ajoy Thamattorr).
15) In "Writing Scripts" section of "Exercises" appendix:
Added "ASCII to Integer" exercise to Intermediate section.
16) In "Contributed Scripts" appendix:
Added "sam.sh" Morse code practice script.
Added "gronsfeld.bash" Gronsfeld Cipher script.
17) Fixed "base64.sh" script. It works now.
18) Epub version of ABS Guide now available, thanks to
Craig Barnes.
19) Miscellaneous bugfixes, minor improvements, and URL updates.
* Vortexberry bushes are nowhere to be found. They were all
uprooted by rampaging unicorns.
Version 6.3, Swozzleberry* release Version 6.3, Swozzleberry* release
30 April, 2011 30 April, 2011
@ -1102,7 +1191,8 @@ Version 5.1, Lingonberry release
20) In "Copyright" appendix: 20) In "Copyright" appendix:
Liberalized the license terms to *permit* modified or derivative Liberalized the license terms to *permit* modified or derivative
versions of the book. versions of the book. However, the Copyright Appendix is invariant
and may not be omitted.
21) Changed "Sony Librie" references to include the newer Sony PRS-500/505 21) Changed "Sony Librie" references to include the newer Sony PRS-500/505
device. device.

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# Du.sh: DOS to UNIX text file converter. # Du.sh: DOS to UNIX text file converter.
E_WRONGARGS=65 E_WRONGARGS=85
if [ -z "$1" ] if [ -z "$1" ]
then then

View File

@ -265,17 +265,31 @@
</itemizedlist></para> </itemizedlist></para>
<para><command>: </command>
<link linkend="nullref">Colon</link>, <firstterm>null</firstterm> <para><command>:</command> Colon
command, equivalent to the
<link linkend="trueref">true</link> Bash builtin
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>
<command>:&gt; <filename>file</filename></command> <command>:&gt; <filename>filename</filename></command>
<link linkend="ioredirectionref">Truncate file</link> <link linkend="ioredirectionref">Truncate file</link>
to zero length</para></listitem> to zero length</para></listitem>
<listitem><para><link
linkend="nullref"><firstterm>null</firstterm>
command</link>, equivalent to the
<link linkend="trueref">true</link> Bash
builtin</para></listitem>
<listitem><para>Used in an <link linkend="anonheredoc0">anonymous
here document</link></para></listitem>
<listitem><para>Used as a <link linkend="fstrangeref">function
name</link></para></listitem>
</itemizedlist></para> </itemizedlist></para>
<para><command>! </command> <para><command>! </command>
<link linkend="notref">Negation operator</link>, inverts <link <link linkend="notref">Negation operator</link>, inverts <link
linkend="negcond">exit status</link> of a test or command linkend="negcond">exit status</link> of a test or command
@ -794,6 +808,8 @@
<!-- ********************** --> <!-- ********************** -->
<para><link linkend="arithexpref">Arithmetic expansion</link> <para><link linkend="arithexpref">Arithmetic expansion</link>
<itemizedlist> <itemizedlist>
<listitem><para><link linkend="arxs">
<firstterm>exit status</firstterm> of</link></para></listitem>
<listitem><para><link linkend="arithexpvar1"> <listitem><para><link linkend="arithexpvar1">
variations of</link></para></listitem> variations of</link></para></listitem>
</itemizedlist></para> </itemizedlist></para>
@ -1190,6 +1206,7 @@
</link>, for handling variables</para> </link>, for handling variables</para>
<para><link linkend="cwsolver">Crossword puzzle solver</link></para> <para><link linkend="cwsolver">Crossword puzzle solver</link></para>
<para><link linkend="gronsfeld">Cryptography</link></para>
<para>Curly brackets {} <para>Curly brackets {}
<itemizedlist> <itemizedlist>
@ -1392,6 +1409,9 @@
references</link></para></listitem> references</link></para></listitem>
<listitem><para><link linkend="evalrisk">Risk of <listitem><para><link linkend="evalrisk">Risk of
using</link></para></listitem> using</link></para></listitem>
<listitem><para><link linkend="samorse">Using
<firstterm>eval</firstterm> to convert <firstterm>array</firstterm>
elements into a command list</link></para></listitem>
<listitem><para><link linkend="arrchoice0">Using <listitem><para><link linkend="arrchoice0">Using
<firstterm>eval</firstterm> to select among <firstterm>eval</firstterm> to select among
variables</link></para></listitem> variables</link></para></listitem>
@ -1559,6 +1579,9 @@
<listitem><para><link linkend="captureretval">Capturing <listitem><para><link linkend="captureretval">Capturing
the return value</link> of a function the return value</link> of a function
using <link linkend="echoref">echo</link></para></listitem> using <link linkend="echoref">echo</link></para></listitem>
<listitem><para><link
linkend="colonfname"><firstterm>Colon</firstterm></link>
as function name</para></listitem>
<listitem><para><link linkend="functdefmust">Definition <listitem><para><link linkend="functdefmust">Definition
must precede</link> first call to function</para></listitem> must precede</link> first call to function</para></listitem>
<listitem><para><link linkend="exitreturn1">Exit <listitem><para><link linkend="exitreturn1">Exit
@ -1586,18 +1609,22 @@
<listitem> <listitem>
<para><link linkend="returnref">return</link></para> <para><link linkend="returnref">return</link></para>
<para>Multiple return values from a function, <para>Multiple <firstterm>return values</firstterm> from
a function,
<link linkend="stddev">example script</link></para> <link linkend="stddev">example script</link></para>
<para><link linkend="retarray"> <para><link linkend="retarray">
Returning an <firstterm>array</firstterm></link> from Returning an <firstterm>array</firstterm></link> from
a function</para> a function</para>
<para><link linkend="rvt"><firstterm>return</firstterm> <para><link linkend="rvt"><firstterm>Return</firstterm>
range limits</link>, workarounds</para> range limits</link>, workarounds</para>
</listitem> </listitem>
<listitem><para><link <listitem><para><link
linkend="fshiftref"><firstterm>shift</firstterm> linkend="fshiftref"><firstterm>Shift</firstterm>
arguments passed</link> to a function</para></listitem> arguments passed</link> to a function</para></listitem>
<listitem><para><link
linkend="fstrangeref">Unusual function
names</link></para></listitem>
</itemizedlist> </itemizedlist>
<para>* * *</para> <para>* * *</para>
@ -1685,6 +1712,7 @@
comparison</link> test</para> comparison</link> test</para>
<para><link linkend="groffref"><firstterm>groff</firstterm></link>, <para><link linkend="groffref"><firstterm>groff</firstterm></link>,
text markup and formatting language</para> text markup and formatting language</para>
<para><link linkend="gronsfeld">Gronsfeld cipher</link></para>
<para><link linkend="groupsref"><varname>$GROUPS</varname></link>, <para><link linkend="groupsref"><varname>$GROUPS</varname></link>,
<firstterm>Groups</firstterm> user belongs to</para> <firstterm>Groups</firstterm> user belongs to</para>
<para><link linkend="gzipref">gzip</link>, compression utility</para> <para><link linkend="gzipref">gzip</link>, compression utility</para>
@ -1739,6 +1767,8 @@
<para>Calculating the <link linkend="goldenratio">Golden <para>Calculating the <link linkend="goldenratio">Golden
Ratio</link></para> Ratio</link></para>
<para><link linkend="hspre">Prepending text</link></para> <para><link linkend="hspre">Prepending text</link></para>
<para><link linkend="hsloop">As the <filename>stdin</filename> of a
<firstterm>loop</firstterm></link></para>
<para><link linkend="hsread">Using <para><link linkend="hsread">Using
<firstterm>read</firstterm></link></para> <firstterm>read</firstterm></link></para>
</listitem> </listitem>
@ -1847,8 +1877,8 @@
<para>* * *</para> <para>* * *</para>
<para><link linkend="jobidtable0">Job IDs</link>, table</para>
<para><link linkend="jobidtable0">Job IDs</link>, table</para>
<para><link linkend="jotref">jot</link>, <para><link linkend="jotref">jot</link>,
Emit a sequence of integers. Equivalent to <link Emit a sequence of integers. Equivalent to <link
linkend="seqref">seq</link>. linkend="seqref">seq</link>.
@ -1856,6 +1886,7 @@
<listitem><para><link linkend="jotrandom">Random sequence <listitem><para><link linkend="jotrandom">Random sequence
generation</link></para></listitem> generation</link></para></listitem>
</itemizedlist></para> </itemizedlist></para>
<para><link linkend="jabh">Just another Bash hacker!</link></para>
<para>* * *</para> <para>* * *</para>
@ -2062,6 +2093,8 @@
<para><link linkend="mathc">Math commands</link></para> <para><link linkend="mathc">Math commands</link></para>
<para><link linkend="metameaningref">Meta-meaning</link></para> <para><link linkend="metameaningref">Meta-meaning</link></para>
<para><link linkend="samorse">Morse code training</link> script</para>
<para><link linkend="moduloref">Modulo</link>, arithmetic <para><link linkend="moduloref">Modulo</link>, arithmetic
<firstterm>remainder</firstterm> operator <firstterm>remainder</firstterm> operator
<itemizedlist> <itemizedlist>
@ -2084,7 +2117,7 @@
</itemizedlist></para> </itemizedlist></para>
<para><link linkend="ncref">nc</link>, <firstterm>netcat</firstterm>, <para><link linkend="ncref">nc</link>, <firstterm>netcat</firstterm>,
a toolkit for TCP and UDP ports</para> a network toolkit for TCP and UDP ports</para>
<para><link linkend="nequalref">-ne</link>, <para><link linkend="nequalref">-ne</link>,
<firstterm>not-equal-to</firstterm> <link <firstterm>not-equal-to</firstterm> <link
linkend="icomparison1">integer comparison</link> test</para> linkend="icomparison1">integer comparison</link> test</para>
@ -2109,6 +2142,20 @@
<para><command>-o </command> <para><command>-o </command>
<link linkend="compoundor">Logical OR</link> <link linkend="compoundor">Logical OR</link>
compound comparison test</para> compound comparison test</para>
<para>Obfuscation
<itemizedlist>
<listitem><para><link
linkend="colonfname"><firstterm>Colon</firstterm></link>
as function name</para></listitem>
<listitem><para><link
linkend="homework">Homework assignment</link></para></listitem>
<listitem><para><link linkend="jabh">Just another Bash
hacker!</link></para>
</listitem>
</itemizedlist>
</para>
<para><link linkend="octalref">octal</link>, base-8 numbers</para> <para><link linkend="octalref">octal</link>, base-8 numbers</para>
<para><link linkend="odref">od</link>, <firstterm>octal <para><link linkend="odref">od</link>, <firstterm>octal
dump</firstterm></para> dump</firstterm></para>
@ -2289,10 +2336,18 @@
using</para></listitem> using</para></listitem>
<listitem><para><link linkend="execperm">Execute permission <listitem><para><link linkend="execperm">Execute permission
lacking</link> for commands within a script</para></listitem> lacking</link> for commands within a script</para></listitem>
<listitem><para> <listitem><para>
<firstterm>Exit status</firstterm>, <firstterm>Exit status</firstterm>,
<link linkend="gotchaexitvalanamalies">anomalous</link> <link linkend="gotchaexitvalanamalies">anomalous</link>
</para></listitem> </para></listitem>
<listitem><para>
<firstterm>Exit status</firstterm>
<link linkend="arxs1">of arithmetic expression <emphasis>not</emphasis>
equivalent to an <firstterm>error code</firstterm></link>
</para></listitem>
<listitem><para><link <listitem><para><link
linkend="parchildprobref"><firstterm>Export</firstterm> linkend="parchildprobref"><firstterm>Export</firstterm>
problem</link>, <firstterm>child</firstterm> process problem</link>, <firstterm>child</firstterm> process
@ -2832,7 +2887,13 @@
linkend="jotref">jot</link>.</para> linkend="jotref">jot</link>.</para>
<para><link linkend="setref">set</link>, <para><link linkend="setref">set</link>,
Change value of internal script variables</para> Change value of internal script variables
<itemizedlist>
<listitem><para><link linkend="undvarerr">set -u</link>,
Abort script with error message if attempting to use
an <firstterm>undeclared</firstterm> variable.</para></listitem>
</itemizedlist>
</para>
<para><link linkend="whatsascript">Shell script</link>, <para><link linkend="whatsascript">Shell script</link>,
definition of</para> definition of</para>

View File

@ -39,7 +39,7 @@ ex71.sh (line 7)
ex71a.sh (line 8) ex71a.sh (line 8)
ex71b.sh (line 22) ex71b.sh (line 22)
logevents.sh (lines 31, 39-42, 47-8, 54, 56, 58, 61, 63, 67) logevents.sh (lines 31, 39-42, 47-8, 54, 56, 58, 61, 63, 67)
m4.sh (line 8: "\&amp;" --> &) m4.sh (line 8: "\&amp;" --> \&)
pw.sh (comment in line 4) pw.sh (comment in line 4)
read-r.sh (lines 5, 6, 20, 27) read-r.sh (lines 5, 6, 20, 27)
rnd.sh (comments in lines 38, 55, 64) rnd.sh (comments in lines 38, 55, 64)
@ -104,7 +104,7 @@ qky.sh
line 87 line 87
line 113 line 113
(The unaltered, executable script can be downloaded. (The unaltered, executable script can be downloaded.
See: http://bash.neuralshortcircuit.com/qky.README.html) See: http://bash.webofcrafts.net/qky.README.html)
maned.sh maned.sh
line 6 (comment) line 6 (comment)
@ -126,3 +126,6 @@ here-commsub.sh
UseGetOpt.sh: line 4 (comment) UseGetOpt.sh: line 4 (comment)
UseGetOpt-2.sh: line 11 (comment) UseGetOpt-2.sh: line 11 (comment)
bash64.sh
line 4 (comment)

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ grep -v 'ed$' # no past tense verbs
# Uses "anagram" utility # Uses "anagram" utility
#+ that is part of the author's "yawl" word list package. #+ that is part of the author's "yawl" word list package.
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz # http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
# http://bash.neuralshortcircuit.com/yawl-0.3.2.tar.gz # http://bash.webofcrafts.net/yawl-0.3.2.tar.gz
exit 0 # End of code. exit 0 # End of code.

View File

@ -5,7 +5,7 @@
# Uses "anagram" utility # Uses "anagram" utility
#+ that is part of the author's "yawl" word list package. #+ that is part of the author's "yawl" word list package.
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz # http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
# http://bash.neuralshortcircuit.com/yawl-0.3.2.tar.gz # http://bash.webofcrafts.net/yawl-0.3.2.tar.gz
E_NOARGS=66 E_NOARGS=66
E_BADARG=67 E_BADARG=67

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# base64.sh: Bash implementation of Base64 encoding and decoding. # base64.sh: Bash implementation of Base64 encoding and decoding.
# #
# Copyright (c) 2011 vladz [vladz@devzero.fr] # Copyright (c) 2011 vladz &lt;vladz@devzero.fr&gt;
# Used in ABSG with permission (thanks!). # Used in ABSG with permission (thanks!).
# #
# Encode or decode original Base64 (and also Base64url) # Encode or decode original Base64 (and also Base64url)
@ -17,9 +17,10 @@
# Reference: # Reference:
# #
# [1] RFC4648 - "The Base16, Base32, and Base64 Data Encodings" # [1] RFC4648 - "The Base16, Base32, and Base64 Data Encodings"
#  http://tools.ietf.org/html/rfc4648#section-5 # http://tools.ietf.org/html/rfc4648#section-5
# The base64_charset[] array contains entire base64 charset,
# The base64_charset[] array contains entire base64 charset,
# and additionally the character "=" ... # and additionally the character "=" ...
base64_charset=( {A..Z} {a..z} {0..9} + / = ) base64_charset=( {A..Z} {a..z} {0..9} + / = )
# Nice illustration of brace expansion. # Nice illustration of brace expansion.
@ -28,12 +29,12 @@ base64_charset=( {A..Z} {a..z} {0..9} + / = )
#+ original base64. #+ original base64.
### base64_charset=( {A..Z} {a..z} {0..9} - _ = ) ### base64_charset=( {A..Z} {a..z} {0..9} - _ = )
# Output text width when encoding # Output text width when encoding
#+ (64 characters, just like openssl output). #+ (64 characters, just like openssl output).
text_width=64 text_width=64
function display_base64_char { function display_base64_char {
#  Convert a 6-bit number (between 0 and 63) into its corresponding values # Convert a 6-bit number (between 0 and 63) into its corresponding values
#+ in Base64, then display the result with the specified text width. #+ in Base64, then display the result with the specified text width.
printf "${base64_charset[$1]}"; (( width++ )) printf "${base64_charset[$1]}"; (( width++ ))
(( width % text_width == 0 )) && printf "\n" (( width % text_width == 0 )) && printf "\n"
@ -41,15 +42,15 @@ function display_base64_char {
function encode_base64 { function encode_base64 {
# Encode three 8-bit hexadecimal codes into four 6-bit numbers. # Encode three 8-bit hexadecimal codes into four 6-bit numbers.
# We need two local int array variables: # We need two local int array variables:
#  c8[]: to store the codes of the 8-bit characters to encode # c8[]: to store the codes of the 8-bit characters to encode
# c6[]: to store the corresponding encoded values on 6-bit # c6[]: to store the corresponding encoded values on 6-bit
declare -a -i c8 c6 declare -a -i c8 c6
# Convert hexadecimal to decimal. # Convert hexadecimal to decimal.
c8=( $(printf "ibase=16; ${1:0:2}\n${1:2:2}\n${1:4:2}\n" | bc) ) c8=( $(printf "ibase=16; ${1:0:2}\n${1:2:2}\n${1:4:2}\n" | bc) )
#  Let's play with bitwise operators # Let's play with bitwise operators
#+ (3x8-bit into 4x6-bits conversion). #+ (3x8-bit into 4x6-bits conversion).
(( c6[0] = c8[0] >> 2 )) (( c6[0] = c8[0] >> 2 ))
(( c6[1] = ((c8[0] & 3) << 4) | (c8[1] >> 4) )) (( c6[1] = ((c8[0] & 3) << 4) | (c8[1] >> 4) ))
@ -70,7 +71,7 @@ function encode_base64 {
function decode_base64 { function decode_base64 {
# Decode four base64 characters into three hexadecimal ASCII characters. # Decode four base64 characters into three hexadecimal ASCII characters.
#  c8[]: to store the codes of the 8-bit characters # c8[]: to store the codes of the 8-bit characters
# c6[]: to store the corresponding Base64 values on 6-bit # c6[]: to store the corresponding Base64 values on 6-bit
declare -a -i c8 c6 declare -a -i c8 c6
@ -86,7 +87,7 @@ function decode_base64 {
c6=( ${c6[*]} ${position} ) c6=( ${c6[*]} ${position} )
done done
#  Let's play with bitwise operators # Let's play with bitwise operators
#+ (4x8-bit into 3x6-bits conversion). #+ (4x8-bit into 3x6-bits conversion).
(( c8[0] = (c6[0] << 2) | (c6[1] >> 4) )) (( c8[0] = (c6[0] << 2) | (c6[1] >> 4) ))
@ -103,9 +104,17 @@ function decode_base64 {
done done
} }
# main ()
if [ $# -eq 0 ]; then # encode
# main ()
if [ "$1" = "-d" ]; then # decode
# Reformat STDIN in pseudo 4x6-bit groups.
content=$(cat - | tr -d "\n" | sed -r "s/(.{4})/\1 /g")
for chars in ${content}; do decode_base64 ${chars}; done
else
# Make a hexdump of stdin and reformat in 3-byte groups. # Make a hexdump of stdin and reformat in 3-byte groups.
content=$(cat - | xxd -ps -u | sed -r "s/(\w{6})/\1 /g" | content=$(cat - | xxd -ps -u | sed -r "s/(\w{6})/\1 /g" |
tr -d "\n") tr -d "\n")
@ -114,16 +123,4 @@ if [ $# -eq 0 ]; then # encode
echo echo
elif [ "$1" = "-d" ]; then # decode
# Reformat STDIN in pseudo 4x6-bit groups.
content=$(cat - | tr -d "\n" | sed -r "s/(.{4})/\1 /g")
for chars in ${content}; do decode_base64 ${chars}; done
else # display usage
echo
printf "Usage: $0 < Infile > Outfile\n"
printf " $0 -d < Infile > Outfile\n"
printf " -d decode\n\n"
fi fi

View File

@ -48,6 +48,7 @@ echo # Blank line at beginning of run.
Show_Slots () { Show_Slots () {
echo; echo
echo -n " " echo -n " "
for i in $( seq $NUMSLOTS ) # Pretty-print array elements. for i in $( seq $NUMSLOTS ) # Pretty-print array elements.
do do
@ -56,7 +57,7 @@ done
echo # Row of slots: echo # Row of slots:
echo " |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|" echo " |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|"
echo " ^^" echo " ||"
echo # Note that if the count within any particular slot exceeds 99, echo # Note that if the count within any particular slot exceeds 99,
#+ it messes up the display. #+ it messes up the display.
# Running only(!) 500 passes usually avoids this. # Running only(!) 500 passes usually avoids this.
@ -86,6 +87,9 @@ done
SHIFT=11 # Why 11, and not 10? SHIFT=11 # Why 11, and not 10?
let "POS += $SHIFT" # Shift "zero position" to center. let "POS += $SHIFT" # Shift "zero position" to center.
(( Slots[$POS]++ )) # DEBUG: echo $POS (( Slots[$POS]++ )) # DEBUG: echo $POS
# echo -n "$POS "
} }
@ -115,3 +119,5 @@ exit $?
#+ a scattergram. #+ a scattergram.
# 2) Alter the script to use /dev/urandom instead of $RANDOM. # 2) Alter the script to use /dev/urandom instead of $RANDOM.
# Will this make the results more random? # Will this make the results more random?
# 3) Provide some sort of "animation" or graphic output
# for each marble played.

View File

@ -28,15 +28,15 @@
#+ Then the ratio of SPLASHES to total shots will approximate #+ Then the ratio of SPLASHES to total shots will approximate
#+ the value of PI/4. #+ the value of PI/4.
# #
# The reason for this is that the cannon is actually shooting # The simplified explanation is that the cannon is actually
#+ only at the upper right-hand quadrant of the square, #+ shooting only at the upper right-hand quadrant of the square,
#+ i.e., Quadrant I of the Cartesian coordinate plane. #+ i.e., Quadrant I of the Cartesian coordinate plane.
# (The previous explanation was a simplification.) #
# #
# Theoretically, the more shots taken, the better the fit. # Theoretically, the more shots taken, the better the fit.
# However, a shell script, as opposed to a compiled language # However, a shell script, as opposed to a compiled language
#+ with floating-point math built in, requires a few compromises. #+ with floating-point math built in, requires some compromises.
# This tends to lower the accuracy of the simulation. # This decreases the accuracy of the simulation.
DIMENSION=10000 # Length of each side of the plot. DIMENSION=10000 # Length of each side of the plot.
@ -44,7 +44,7 @@ DIMENSION=10000 # Length of each side of the plot.
MAXSHOTS=1000 # Fire this many shots. MAXSHOTS=1000 # Fire this many shots.
# 10000 or more would be better, but would take too long. # 10000 or more would be better, but would take too long.
PMULTIPLIER=4.0 # Scaling factor to approximate PI. PMULTIPLIER=4.0 # Scaling factor.
declare -r M_PI=3.141592654 declare -r M_PI=3.141592654
# Actual 9-place value of PI, for comparison purposes. # Actual 9-place value of PI, for comparison purposes.
@ -68,13 +68,13 @@ EOF
) )
# Setting "scale" to zero rounds down result to integer value, # Setting "scale" to zero rounds down result to integer value,
#+ a necessary compromise in this script. #+ a necessary compromise in this script.
# This decreases the accuracy of the simulation. # It decreases the accuracy of this simulation.
} }
# ========================================================== # ==========================================================
# main() { # main() {
# "Main" code block, mimmicking a C-language main() function. # "Main" code block, mimicking a C-language main() function.
# Initialize variables. # Initialize variables.
shots=0 shots=0
@ -119,9 +119,9 @@ done
echo echo
echo "After $shots shots, PI looks like approximately $Pi" echo "After $shots shots, PI looks like approximately $Pi"
# Tends to run a bit high, # Tends to run a bit high,
#+ probably due to round-off error and imperfect randomness of $RANDOM. #+ possibly due to round-off error and imperfect randomness of $RANDOM.
# But still usually within plus-or-minus 5% . . . # But still usually within plus-or-minus 5% . . .
#+ a pretty good rough approximation. #+ a pretty fair rough approximation.
error=$(echo "scale=9; $Pi - $M_PI" | bc) error=$(echo "scale=9; $Pi - $M_PI" | bc)
pct_error=$(echo "scale=2; 100.0 * $error / $M_PI" | bc) pct_error=$(echo "scale=2; 100.0 * $error / $M_PI" | bc)
echo -n "Deviation from mathematical value of PI = $error" echo -n "Deviation from mathematical value of PI = $error"
@ -132,7 +132,7 @@ echo
# } # }
# ========================================================== # ==========================================================
exit exit 0
# One might well wonder whether a shell script is appropriate for # One might well wonder whether a shell script is appropriate for
#+ an application as complex and computation-intensive as a simulation. #+ an application as complex and computation-intensive as a simulation.

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# case-cmd.sh: Using command substitution to generate a "case" variable. # case-cmd.sh: Using command substitution to generate a "case" variable.
case $( arch ) in # "arch" returns machine architecture. case $( arch ) in # $( arch ) returns machine architecture.
# Equivalent to 'uname -m' ... # Equivalent to 'uname -m' ...
i386 ) echo "80386-based machine";; i386 ) echo "80386-based machine";;
i486 ) echo "80486-based machine";; i486 ) echo "80486-based machine";;

View File

@ -11,7 +11,7 @@
# 6) NUMBER &lt;-- result # 6) NUMBER &lt;-- result
# 7) Loop back to step 3 (for specified number of iterations). # 7) Loop back to step 3 (for specified number of iterations).
# #
# The theory is that every sequence, # The theory is that every such sequence,
#+ no matter how large the initial value, #+ no matter how large the initial value,
#+ eventually settles down to repeating "4,2,1..." cycles, #+ eventually settles down to repeating "4,2,1..." cycles,
#+ even after fluctuating through a wide range of values. #+ even after fluctuating through a wide range of values.
@ -29,7 +29,7 @@ h=${1:-$$} # Seed.
#+ if not specified as command-line arg. #+ if not specified as command-line arg.
echo echo
echo "C($h) --- $MAX_ITERATIONS Iterations" echo "C($h) -*- $MAX_ITERATIONS Iterations"
echo echo
for ((i=1; i<=MAX_ITERATIONS; i++)) for ((i=1; i<=MAX_ITERATIONS; i++))

View File

@ -2,10 +2,11 @@
# --------------------------------------------------------- # ---------------------------------------------------------
# Suppose I have a large number of jobs that need to be run, with # Suppose I have a large number of jobs that need to be run, with
#+ any data that is to be treated in files of a given name pattern in a #+ any data that is to be treated in files of a given name pattern
#+ directory. There are several machines that access this directory, and #+ in a directory. There are several machines that access
#+ I want to distribute the work over these different boxen. Then I #+ this directory, and I want to distribute the work over these
#+ usually nohup something like the following on every box: #+ different boxen.
# Then I usually nohup something like the following on every box:
while true while true
do do
@ -26,6 +27,8 @@ do
break break
done done
exit 0
# The details, in particular the sleep N, are particular to my # The details, in particular the sleep N, are particular to my
#+ application, but the general pattern is: #+ application, but the general pattern is:

View File

@ -20,7 +20,7 @@ DICT=/usr/share/dict/word.lst
#+ download the author's "yawl" word list package. #+ download the author's "yawl" word list package.
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz # http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
# or # or
# http://bash.neuralshortcircuit.com/yawl-0.3.2.tar.gz # http://bash.webofcrafts.net/yawl-0.3.2.tar.gz
if [ -z "$1" ] # If no word pattern specified if [ -z "$1" ] # If no word pattern specified

View File

@ -5,7 +5,7 @@
dereference () dereference ()
{ {
y=\$"$1" # Name of variable. y=\$"$1" # Name of variable (not value!).
echo $y # $Junk echo $y # $Junk
x=`eval "expr \"$y\" "` x=`eval "expr \"$y\" "`

View File

@ -274,7 +274,7 @@ IndexList()
The key (no pun intended) to a Unified Content File System (UCFS) The key (no pun intended) to a Unified Content File System (UCFS)
is to distinguish the files in the system based on their content. is to distinguish the files in the system based on their content.
Distinguishing files by their name is just, so, 20th Century. Distinguishing files by their name is just so 20th Century.
The content is distinguished by computing a checksum of that content. The content is distinguished by computing a checksum of that content.
This version uses the md5sum program to generate a 128 bit checksum This version uses the md5sum program to generate a 128 bit checksum

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
# escaped.sh: escaped characters # escaped.sh: escaped characters
echo; echo
############################################################# #############################################################
### First, let's show some basic escaped-character usage. ### ### First, let's show some basic escaped-character usage. ###
############################################################# #############################################################
@ -41,22 +39,19 @@ echo "=============="
# The $'\X' construct makes the -e option unnecessary. # The $'\X' construct makes the -e option unnecessary.
echo; echo "NEWLINE AND BEEP" echo; echo "NEWLINE and (maybe) BEEP"
echo $'\n' # Newline. echo $'\n' # Newline.
echo $'\a' # Alert (beep). echo $'\a' # Alert (beep).
# May only flash, not beep, depending on terminal.
echo "---------------" # We have seen $'\nnn" string expansion, and now . . .
echo "QUOTATION MARKS"
echo "---------------"
echo; echo; echo
# Here we have seen $'\nnn" string expansion.
# =================================================================== # # =================================================================== #
# Version 2 of Bash introduced the $'\nnn' string expansion construct. # Version 2 of Bash introduced the $'\nnn' string expansion construct.
# =================================================================== # # =================================================================== #
echo "Introducing the \$\' ... \' string-expansion construct!" echo "Introducing the \$\' ... \' string-expansion construct . . . "
echo echo ". . . featuring more quotation marks."
echo $'\t \042 \t' # Quote (") framed by tabs. echo $'\t \042 \t' # Quote (") framed by tabs.
# Note that '\nnn' is an octal value. # Note that '\nnn' is an octal value.
@ -66,15 +61,13 @@ echo $'\t \x22 \t' # Quote (") framed by tabs.
# Thank you, Greg Keraunen, for pointing this out. # Thank you, Greg Keraunen, for pointing this out.
# Earlier Bash versions allowed '\x022'. # Earlier Bash versions allowed '\x022'.
echo "==============="
echo echo
# Assigning ASCII characters to a variable. # Assigning ASCII characters to a variable.
# ---------------------------------------- # ----------------------------------------
quote=$'\042' # " assigned to a variable. quote=$'\042' # " assigned to a variable.
echo "$quote This is a quoted string, $quote and this lies outside the quotes." echo "$quote Quoted string $quote and this lies outside the quotes."
echo echo
@ -87,12 +80,12 @@ echo
ABC=$'\101\102\103\010' # 101, 102, 103 are octal A, B, C. ABC=$'\101\102\103\010' # 101, 102, 103 are octal A, B, C.
echo $ABC echo $ABC
echo; echo echo
escape=$'\033' # 033 is octal for escape. escape=$'\033' # 033 is octal for escape.
echo "\"escape\" echoes as $escape" echo "\"escape\" echoes as $escape"
# no visible output. # no visible output.
echo; echo echo
exit 0 exit 0

View File

@ -3,9 +3,9 @@
# View gzipped files with 'more' filter. # View gzipped files with 'more' filter.
E_NOARGS=65 E_NOARGS=85
E_NOTFOUND=66 E_NOTFOUND=86
E_NOTGZIP=67 E_NOTGZIP=87
if [ $# -eq 0 ] # same effect as: if [ -z "$1" ] if [ $# -eq 0 ] # same effect as: if [ -z "$1" ]
# $1 can exist, but be empty: zmore "" arg2 arg3 # $1 can exist, but be empty: zmore "" arg2 arg3

View File

@ -15,8 +15,13 @@ tr a-z A-Z <"$1"
# tr '[:lower:]' '[:upper:]' <"$1" # tr '[:lower:]' '[:upper:]' <"$1"
# Thanks, S.C. # Thanks, S.C.
# Or even . . .
# cat "$1" | tr a-z A-Z
# Or dozens of other ways . . .
exit 0 exit 0
# Exercise: # Exercise:
# Rewrite this script to give the option of changing a file # Rewrite this script to give the option of changing a file
#+ to *either* upper or lowercase. #+ to *either* upper or lowercase.
# Hint: Use either the "case" or "select" command.

View File

@ -4,18 +4,18 @@
# Script by Stephane Chazelas. # Script by Stephane Chazelas.
# Somewhat modified by ABS Guide author. # Somewhat modified by ABS Guide author.
infile=$0 # This script. infile=$0 # This script.
outfile=log.txt # Output file left behind. outfile=log.txt # Output file left behind.
n=3 n=8
p=5 p=11
dd if=$infile of=$outfile bs=1 skip=$((n-1)) count=$((p-n+1)) 2> /dev/null dd if=$infile of=$outfile bs=1 skip=$((n-1)) count=$((p-n+1)) 2> /dev/null
# Extracts characters n to p (3 to 5) from this script. # Extracts characters n to p (8 to 11) from this script ("bash").
# -------------------------------------------------------- # ----------------------------------------------------------------
echo -n "hello world" | dd cbs=1 conv=unblock 2> /dev/null echo -n "hello vertical world" | dd cbs=1 conv=unblock 2> /dev/null
# Echoes "hello world" vertically. # Echoes "hello vertical world" vertically downward.
# Why? A newline follows each character dd emits. # Why? A newline follows each character dd emits.
exit 0 exit $?

View File

@ -7,6 +7,7 @@
MAILDIR=~/mail/* # No quoting of variable. Why? MAILDIR=~/mail/* # No quoting of variable. Why?
# Maybe check if exists $MAILDIR . . . if [ -d $MAILDIR ] . . .
GREP_OPTS="-H -A 5 --color" # Show file, plus extra context lines GREP_OPTS="-H -A 5 --color" # Show file, plus extra context lines
#+ and display "From" in color. #+ and display "From" in color.
TARGETSTR="^From" # "From" at beginning of line. TARGETSTR="^From" # "From" at beginning of line.
@ -20,5 +21,5 @@ done
exit $? exit $?
# Might wish to pipe the output of this script to 'more' or # You might wish to pipe the output of this script to 'more'
#+ redirect it to a file . . . #+ or redirect it to a file . . .

View File

@ -0,0 +1,147 @@
#!/bin/bash
# gronsfeld.bash
# License: GPL3
# Reldate 06/23/11
# This is an implementation of the Gronsfeld Cipher.
# It's essentially a stripped-down variant of the
#+ polyalphabetic Vigen&egrave;re Tableau, but with only 10 alphabets.
# The classic Gronsfeld has a numerical sequence as the key word,
#+ but instead we substitute a letter string, for ease of use.
# Allegedly, this cipher was invented by the eponymous Count Gronsfeld
#+ in the 17th Century. It was at one time considered to be unbreakable.
# Note that this is ###not### a secure cipher by modern standards.
# Global Variables #
Enc_suffix="29378" # Encrypted text output with this 5-digit suffix.
# This functions as a decryption flag,
#+ and when used to generate passwords adds security.
Default_key="gronsfeldk"
# The script uses this if key not entered below
# (at "Keychain").
# Change the above two values frequently
#+ for added security.
GROUPLEN=5 # Output in groups of 5 letters, per tradition.
alpha1=( abcdefghijklmnopqrstuvwxyz )
alpha2=( {A..Z} ) # Output in all caps, per tradition.
# Use alpha2=( {a..z} ) for password generator.
wraplen=26 # Wrap around if past end of alphabet.
dflag= # Decrypt flag (set if $Enc_suffix present).
E_NOARGS=76 # Missing command-line args?
DEBUG=77 # Debugging flag.
declare -a offsets # This array holds the numerical shift values for
#+ encryption/decryption.
########Keychain#########
key= ### Put key here!!!
# 10 characters!
#########################
# Function
: ()
{ # Encrypt or decrypt, depending on whether $dflag is set.
# Why ": ()" as a function name? Just to prove that it can be done.
local idx keydx mlen off1 shft
local plaintext="$1"
local mlen=${#plaintext}
for (( idx=0; idx<$mlen; idx++ ))
do
let "keydx = $idx % $keylen"
shft=${offsets[keydx]}
if [ -n "$dflag" ]
then # Decrypt!
let "off1 = $(expr index "${alpha1[*]}" ${plaintext:idx:1}) - $shft"
# Shift backward to decrypt.
else # Encrypt!
let "off1 = $(expr index "${alpha1[*]}" ${plaintext:idx:1}) + $shft"
# Shift forward to encrypt.
test $(( $idx % $GROUPLEN)) = 0 && echo -n " " # Groups of 5 letters.
# Comment out above line for output as a string without whitespace,
# for example, if using the script as a password generator.
fi
((off1--)) # Normalize.
if [ $off1 -lt 0 ]
then # Catch negative indices.
let "off1 += $wraplen"
fi
((off1 %= $wraplen)) # Wrap around if past end of alphabet.
echo -n "${alpha2[off1]}"
done
if [ -z "$dflag" ]
then
echo " $Enc_suffix"
# echo "$Enc_suffix" # For password generator.
else
echo
fi
} # End encrypt/decrypt function.
# int main () {
# Check if command-line args.
if [ -z "$1" ]
then
echo "Usage: $0 TEXT TO ENCODE/DECODE"
exit $E_NOARGS
fi
if [ ${!#} == "$Enc_suffix" ]
# ^^^^^ Final command-line arg.
then
dflag=ON
echo -n "+" # Flag decrypted text with a "+" for easy ID.
fi
if [ -z "$key" ]
then
key="$Default_key" # "gronsfeldk" per above.
fi
keylen=${#key}
for (( idx=0; idx<$keylen; idx++ ))
do # Calculate shift values for encryption/decryption.
offsets[idx]=$(expr index "${alpha1[*]}" ${key:idx:1}) # Normalize.
((offsets[idx]--)) # Necessary because "expr index" starts at 1,
#+ whereas array count starts at 0.
# Generate array of numerical offsets corresponding to the key.
# There are simpler ways to accomplish this.
done
args=$(echo "$*" | sed -e 's/ //g' | tr A-Z a-z | sed -e 's/[0-9]//g')
# Remove whitespace and digits from command-line args.
# Can modify to also remove punctuation characters, if desired.
# Debug:
# echo "$args"; exit $DEBUG
: "$args" # Call the function named ":".
# : is a null operator, except . . . when it's a function name!
exit $? # } End-of-script
# ************************************************************** #
# This script can function as a password generator,
#+ with several minor mods, see above.
# That would allow an easy-to-remember password, even the word
#+ "password" itself, which encrypts to vrgfotvo29378
#+ a fairly secure password not susceptible to a dictionary attack.
# Or, you could use your own name (surely that's easy to remember!).
# For example, Bozo Bozeman encrypts to hfnbttdppkt29378.
# ************************************************************** #

View File

@ -102,7 +102,7 @@ Optional environment variables
Additional documentation Additional documentation
Download the archived set of scripts Download the archived set of scripts
explaining and illustrating the function contained within this script. explaining and illustrating the function contained within this script.
http://bash.neuralshortcircuit.com/mszick_clf.tar.bz2 http://bash.webofcrafts.net/mszick_clf.tar.bz2
Study notes Study notes

View File

@ -1,5 +1,7 @@
#!/bin/bash #!/bin/bash
# life.sh: "Life in the Slow Lane" # life.sh: "Life in the Slow Lane"
# Author: Mendel Cooper
# License: GPL3
# Version 0.2: Patched by Daniel Albers # Version 0.2: Patched by Daniel Albers
#+ to allow non-square grids as input. #+ to allow non-square grids as input.
@ -11,8 +13,8 @@
# --------------------------------------------------------------------- # # --------------------------------------------------------------------- #
# 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.# # Designate a living cell with a dot, and a dead one with a blank space.#
# Begin with an arbitrarily drawn dot-and-blank grid, # # Begin with an arbitrarily drawn dot-and-blank grid, #
#+ and let this be the starting generation, "generation 0." # #+ and let this be the starting generation: generation 0. #
# Determine each successive generation by the following rules: # # Determine each successive generation by the following rules: #
# 1) Each cell has 8 neighbors, the adjoining cells # # 1) Each cell has 8 neighbors, the adjoining cells #
#+ left, right, top, bottom, and the 4 diagonals. # #+ left, right, top, bottom, and the 4 diagonals. #
@ -23,7 +25,7 @@
# # # #
# 2) A living cell with either 2 or 3 living neighbors remains alive. # # 2) A living cell with either 2 or 3 living neighbors remains alive. #
SURVIVE=2 # SURVIVE=2 #
# 3) A dead cell with 3 living neighbors comes alive (a "birth"). # # 3) A dead cell with 3 living neighbors comes alive, a "birth." #
BIRTH=3 # BIRTH=3 #
# 4) All other cases result in a dead cell for the next generation. # # 4) All other cases result in a dead cell for the next generation. #
# ##################################################################### # # ##################################################################### #
@ -56,13 +58,13 @@ ALIVE1=.
DEAD1=_ 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, # This script uses a 10 x 10 grid (may be increased,
#+ but a large grid will slow execution). #+ but a large grid will slow down execution).
ROWS=10 ROWS=10
COLS=10 COLS=10
# Change above two variables to match grid size, as desired. # Change above two variables to match desired grid size.
# ---------------------------------------------------------- # # -----------------------------------------------------#
GENERATIONS=10 # How many generations to cycle through. GENERATIONS=10 # How many generations to cycle through.
# Adjust this upwards # Adjust this upwards
@ -70,7 +72,7 @@ GENERATIONS=10 # How many generations to cycle through.
NONE_ALIVE=85 # Exit status on premature bailout, NONE_ALIVE=85 # Exit status on premature bailout,
#+ if no cells left alive. #+ if no cells left alive.
DELAY=2 # Pause between generations, etc. DELAY=2 # Pause between generations.
TRUE=0 TRUE=0
FALSE=1 FALSE=1
ALIVE=0 ALIVE=0
@ -127,7 +129,7 @@ return
} }
IsValid () # Test whether cell coordinate valid. IsValid () # Test if cell coordinate valid.
{ {
if [ -z "$1" -o -z "$2" ] # Mandatory arguments missing? if [ -z "$1" -o -z "$2" ] # Mandatory arguments missing?
@ -179,7 +181,7 @@ IsAlive () # Test whether cell is alive.
return $ALIVE return $ALIVE
fi fi
return $DEAD # Dead, by default. return $DEAD # Defaults to dead.
} }
@ -232,7 +234,7 @@ GetCount () # Count live cells in passed cell's neighborhood.
if [ $? -eq "$TRUE" ] if [ $? -eq "$TRUE" ]
then then
if [ ${array[$t_top]} = "$ALIVE1" ] # Redundancy here. if [ ${array[$t_top]} = "$ALIVE1" ] # Redundancy here.
then # Can be optimized? then # Can it be optimized?
let "count += 1" let "count += 1"
fi fi
fi fi
@ -270,7 +272,7 @@ array=( `echo "$1"` ) # Convert passed arg to array.
while [ "$i" -lt "$cells" ] while [ "$i" -lt "$cells" ]
do do
IsAlive "$1" $i ${array[$i]} # Is cell alive? IsAlive "$1" $i ${array[$i]} # Is the cell alive?
if [ $? -eq "$ALIVE" ] if [ $? -eq "$ALIVE" ]
then # If alive, then then # If alive, then
array[$i]=. #+ represent the cell as a period. array[$i]=. #+ represent the cell as a period.
@ -281,8 +283,8 @@ do
done done
# let "generation += 1" # Increment generation count. # let "generation += 1" # Increment generation count.
# Why was the above line commented out? ### Why was the above line commented out?
# Set variable to pass as parameter to "display" function. # Set variable to pass as parameter to "display" function.
@ -304,6 +306,7 @@ fi #+ if no live cells.
# ========================================================= # =========================================================
# main () # main ()
# {
# Load initial array with contents of startup file. # Load initial array with contents of startup file.
initial=( `cat "$startfile" | sed -e '/#/d' | tr -d '\n' |\ initial=( `cat "$startfile" | sed -e '/#/d' | tr -d '\n' |\
@ -358,6 +361,7 @@ done
# ============================================================== # ==============================================================
echo echo
# }
exit 0 # CEOF:EOF exit 0 # CEOF:EOF
@ -381,4 +385,4 @@ exit 0 # CEOF:EOF
#+ in the script for an altered grid size. #+ in the script for an altered grid size.
# #
# Exercise: Optimize this script. # Exercise: Optimize this script.
# It has some redundant code. # It has redundant code.

View File

@ -8,7 +8,8 @@ echo "substr($string,4)" | m4 # A01
echo "regexp($string,[0-1][0-1],\&amp;Z)" | m4 # 01Z echo "regexp($string,[0-1][0-1],\&amp;Z)" | m4 # 01Z
# Arithmetic # Arithmetic
echo "incr(22)" | m4 # 23 var=99
echo "eval(99 / 3)" | m4 # 33 echo "incr($var)" | m4 # 100
echo "eval($var / 3)" | m4 # 33
exit exit

View File

@ -23,19 +23,20 @@ then #+ valid file argument.
fi fi
# SORT="sort" # No longer necessary to define options # SORT="sort" # No longer necessary to define
#+ to sort. Changed from original script. #+ options to sort. Changed from
#+ original script.
cat $* | # Contents of specified files to stdout. cat $* | # Contents of specified files to stdout.
tr A-Z a-z | # Convert to lowercase. tr A-Z a-z | # Convert to lowercase.
tr ' ' '\012' | # New: change spaces to newlines. tr ' ' '\012' | # New: change spaces to newlines.
# tr -cd '\012[a-z][0-9]' | # Get rid of everything non-alphanumeric # tr -cd '\012[a-z][0-9]' | # Get rid of everything
#+ (in original script). #+ non-alphanumeric (in orig. script).
tr -c '\012a-z' '\012' | # Rather than deleting non-alpha chars, tr -c '\012a-z' '\012' | # Rather than deleting non-alpha
#+ change them to newlines. #+ chars, change them to newlines.
sort | # $SORT options unnecessary now. sort | # $SORT options unnecessary now.
uniq | # Remove duplicates. uniq | # Remove duplicates.
grep -v '^#' | # Delete lines beginning with a hashmark. grep -v '^#' | # Delete lines starting with hashmark.
grep -v '^$' # Delete blank lines. grep -v '^$' # Delete blank lines.
exit 0 exit 0

View File

@ -62,6 +62,9 @@ progname ()
else else
echo "Error! No input." # Mandatory input. echo "Error! No input." # Mandatory input.
exit $E_NOINPUT # Critical! exit $E_NOINPUT # Critical!
# Exercise: The script-abort if no filename input is a bit clumsy.
# Rewrite this section so a default filename is used
#+ if no input.
fi fi
echo -n " \"$section\"">>$savefile # Append, always append. echo -n " \"$section\"">>$savefile # Append, always append.
@ -139,5 +142,6 @@ end # ... exit not needed.
# Exercise (difficult): Fix this! # Exercise (difficult): Fix this!
# This script is not nearly as elaborate as the # This script is not nearly as elaborate as the
#+ full-featured "manedit" package (http://wolfpack.twu.net), #+ full-featured "manedit" package
#+ http://freshmeat.net/projects/manedit/
#+ but it's much easier to use. #+ but it's much easier to use.

View File

@ -6,8 +6,8 @@
#+ "mcalc" (mortgage calculator) package, #+ "mcalc" (mortgage calculator) package,
#+ by Jeff Schmidt #+ by Jeff Schmidt
#+ and #+ and
#+ Mendel Cooper (yours truly, the author of the ABS Guide). #+ Mendel Cooper (yours truly, the ABS Guide author).
# http://www.ibiblio.org/pub/Linux/apps/financial/mcalc-1.6.tar.gz [15k] # http://www.ibiblio.org/pub/Linux/apps/financial/mcalc-1.6.tar.gz
echo echo
echo "Given the principal, interest rate, and term of a mortgage," echo "Given the principal, interest rate, and term of a mortgage,"

View File

@ -17,17 +17,15 @@ multiply () # Multiplies params passed.
mult1=15383; mult2=25211 mult1=15383; mult2=25211
val1=`multiply $mult1 $mult2` val1=`multiply $mult1 $mult2`
echo "$mult1 X $mult2 = $val1" # Assigns stdout (echo) of function to the variable val1.
# 387820813 echo "$mult1 X $mult2 = $val1" # 387820813
mult1=25; mult2=5; mult3=20 mult1=25; mult2=5; mult3=20
val2=`multiply $mult1 $mult2 $mult3` val2=`multiply $mult1 $mult2 $mult3`
echo "$mult1 X $mult2 X $mult3 = $val2" echo "$mult1 X $mult2 X $mult3 = $val2" # 2500
# 2500
mult1=188; mult2=37; mult3=25; mult4=47 mult1=188; mult2=37; mult3=25; mult4=47
val3=`multiply $mult1 $mult2 $mult3 $mult4` val3=`multiply $mult1 $mult2 $mult3 $mult4`
echo "$mult1 X $mult2 X $mult3 X $mult4 = $val3" echo "$mult1 X $mult2 X $mult3 X $mult4 = $val3" # 8173300
# 8173300
exit 0 exit 0

View File

@ -3,7 +3,7 @@ Belisarius
Capablanca Capablanca
Euler Euler
Goethe Goethe
Hamurabi Hegel
Jonah Jonah
Laplace Laplace
Maroczy Maroczy
@ -13,7 +13,7 @@ Semmelweiss
Smith Smith
Turing Turing
Venn Venn
Wilkinson Warshawski
Znosko-Borowski Znosko-Borowski
# This is a data file for # This is a data file for

View File

@ -3,6 +3,8 @@
# Requires Bash, version -ge 4.2. # Requires Bash, version -ge 4.2.
array=( zero one two three four five ) # Six-element array. array=( zero one two three four five ) # Six-element array.
# 0 1 2 3 4 5
# -6 -5 -4 -3 -2 -1
# Negative array indices now permitted. # Negative array indices now permitted.
echo ${array[-1]} # five echo ${array[-1]} # five
@ -34,3 +36,5 @@ done # Lists the elements in the array, backwards.
# We have just simulated the "tac" command on this array. # We have just simulated the "tac" command on this array.
echo echo
# See also neg-offset.sh.

View File

@ -1,21 +1,26 @@
#!/bin/bash #!/bin/bash
# Bash, version -ge 4.2 # Bash, version -ge 4.2
# Negative length-index in substring extraction. # Negative length-index in substring extraction.
# Important: This changes the interpretation of this construct! # Important: It changes the interpretation of this construct!
stringZ=abcABC123ABCabc stringZ=abcABC123ABCabc
echo ${stringZ} # abcABC123ABCabc echo ${stringZ} # abcABC123ABCabc
# Position within string: 0123456789.....
echo ${stringZ:2:3} # cAB echo ${stringZ:2:3} # cAB
# Count 2 chars forward from string beginning, and extract 3 chars. # Count 2 chars forward from string beginning, and extract 3 chars.
# ${string:position:length} # ${string:position:length}
# So far, nothing new, but now ... # So far, nothing new, but now ...
# abcABC123ABCabc
# Position within string: 0123....6543210
echo ${stringZ:3:-6} # ABC123 echo ${stringZ:3:-6} # ABC123
# ^ # ^
# Index 3 chars forward from beginning and 6 chars backward from end, # Index 3 chars forward from beginning and 6 chars backward from end,
#+ and extract everything in between. #+ and extract everything in between.
# ${string:offset-from-front:offset-from-end} # ${string:offset-from-front:offset-from-end}
# When the "length" parameter is negative, # When the "length" parameter is negative,
#+ it serves as an "offset-from-end" parameter. #+ it serves as an offset-from-end parameter.
# See also neg-array.sh.

View File

@ -8,6 +8,7 @@
# This does a backup from the host computer to a locally connected # This does a backup from the host computer to a locally connected
#+ firewire HDD using rsync and ssh. #+ firewire HDD using rsync and ssh.
# (Script should work with USB-connected device (see lines 40-43).
# It then rotates the backups. # It then rotates the backups.
# Run it via cron every night at 5am. # Run it via cron every night at 5am.
# This only backs up the home directory. # This only backs up the home directory.
@ -39,6 +40,7 @@ LOCAL_USER=rjn # User whose home directory should be backed up.
MOUNT_POINT=/backup # Mountpoint of backup drive. MOUNT_POINT=/backup # Mountpoint of backup drive.
# NO trailing slash! # NO trailing slash!
# This must be unique (eg using a udev symlink) # This must be unique (eg using a udev symlink)
# MOUNT_POINT=/media/disk # For USB-connected device.
SOURCE_DIR=/home/$LOCAL_USER # NO trailing slash - it DOES matter to rsync. SOURCE_DIR=/home/$LOCAL_USER # NO trailing slash - it DOES matter to rsync.
BACKUP_DEST_DIR=$MOUNT_POINT/backup/`hostname -s`.${LOCAL_USER}.nightly_backup BACKUP_DEST_DIR=$MOUNT_POINT/backup/`hostname -s`.${LOCAL_USER}.nightly_backup
DRY_RUN=false #If true, invoke rsync with -n, to do a dry run. DRY_RUN=false #If true, invoke rsync with -n, to do a dry run.

View File

@ -0,0 +1,31 @@
#! /bin/bash
# progress-bar2.sh
# Author: Graham Ewart (with reformatting by ABS Guide author).
# Used in ABS Guide with permission (thanks!).
# Invoke this script with bash. It doesn't work with sh.
interval=1
long_interval=10
{
trap "exit" SIGUSR1
sleep $interval; sleep $interval
while true
do
echo -n '.' # Use dots.
sleep $interval
done; } & # Start a progress bar as a background process.
pid=$!
trap "echo !; kill -USR1 $pid; wait $pid" EXIT # To handle ^C.
echo -n 'Long-running process '
sleep $long_interval
echo ' Finished!'
kill -USR1 $pid
wait $pid # Stop the progress bar.
trap EXIT
exit $?

View File

@ -8,6 +8,8 @@ while read
do do
array0[${#array0[@]}]="$REPLY" array0[${#array0[@]}]="$REPLY"
done < <( sed -e 's/bash/CRASH-BANG!/' $0 | grep bin | awk '{print $1}' ) done < <( sed -e 's/bash/CRASH-BANG!/' $0 | grep bin | awk '{print $1}' )
# Sets the default 'read' variable, $REPLY, by process substitution,
#+ then copies it into an array.
echo "${array0[@]}" echo "${array0[@]}"

View File

@ -13,7 +13,7 @@ WLIST=/usr/share/dict/word.lst
# ^^^^^^^^ Word list file found here. # ^^^^^^^^ Word list file found here.
# ASCII word list, one word per line, UNIX format. # ASCII word list, one word per line, UNIX format.
# A suggested list is the script author's "yawl" word list package. # A suggested list is the script author's "yawl" word list package.
# http://bash.neuralshortciruit.com/yawl-0.3.2.tar.gz # http://bash.webofcrafts.net/yawl-0.3.2.tar.gz
# or # or
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz # http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
@ -462,4 +462,4 @@ exit $?
# 7) Fix bugs!!! # 7) Fix bugs!!!
# Reference for more info: # Reference for more info:
# http://bash.neuralshortcircuit.com/qky.README.html # http://bash.webofcrafts.net/qky.README.html

View File

@ -0,0 +1,157 @@
#!/bin/bash
# sam.sh, v. 01
# Still Another Morse (code training script)
# With apologies to Sam (F.B.) Morse.
# Author: Mendel Cooper
# License: GPL3
# Reldate: 05/25/11
# Morse code training script.
# Converts arguments to audible dots and dashes.
# Note: lowercase input only at this time.
# Get the wav files from the source tarball:
# http://bash.webofcrafts.net/abs-guide-latest.tar.bz2
DOT='soundfiles/dot.wav'
DASH='soundfiles/dash.wav'
# Maybe move soundfiles to /usr/local/sounds?
LETTERSPACE=300000 # Microseconds.
WORDSPACE=980000
# Nice and slow, for beginners. Maybe 5 wpm?
EXIT_MSG="May the Morse be with you!"
E_NOARGS=75 # No command-line args?
declare -A morse # Associative array!
# ======================================= #
morse[a]="dot; dash"
morse[b]="dash; dot; dot; dot"
morse[c]="dash; dot; dash; dot"
morse[d]="dash; dot; dot"
morse[e]="dot"
morse[f]="dot; dot; dash; dot"
morse[g]="dash; dash; dot"
morse[h]="dot; dot; dot; dot"
morse[i]="dot; dot;"
morse[j]="dot; dash; dash; dash"
morse[k]="dash; dot; dash"
morse[l]="dot; dash; dot; dot"
morse[m]="dash; dash"
morse[n]="dash; dot"
morse[o]="dash; dash; dash"
morse[p]="dot; dash; dash; dot"
morse[q]="dash; dash; dot; dash"
morse[r]="dot; dash; dot"
morse[s]="dot; dot; dot"
morse[t]="dash"
morse[u]="dot; dot; dash"
morse[v]="dot; dot; dot; dash"
morse[w]="dot; dash; dash"
morse[x]="dash; dot; dot; dash"
morse[y]="dash; dot; dash; dash"
morse[z]="dash; dash; dot; dot"
morse[0]="dash; dash; dash; dash; dash"
morse[1]="dot; dash; dash; dash; dash"
morse[2]="dot; dot; dash; dash; dash"
morse[3]="dot; dot; dot; dash; dash"
morse[4]="dot; dot; dot; dot; dash"
morse[5]="dot; dot; dot; dot; dot"
morse[6]="dash; dot; dot; dot; dot"
morse[7]="dash; dash; dot; dot; dot"
morse[8]="dash; dash; dash; dot; dot"
morse[8]="dash; dash; dash; dash; dot"
# The following must be escaped or quoted.
morse[?]="dot; dot; dash; dash; dot; dot"
morse[.]="dot; dash; dot; dash; dot; dash"
morse[,]="dash; dash; dot; dot; dash; dash"
morse[/]="dash; dot; dot; dash; dot"
morse[\@]="dot; dash; dash; dot; dash; dot"
# ======================================= #
play_letter ()
{
eval ${morse[$1]} # Play dots, dashes from appropriate sound files.
# Why is 'eval' necessary here?
usleep $LETTERSPACE # Pause in between letters.
}
extract_letters ()
{ # Slice string apart, letter by letter.
local pos=0 # Starting at left end of string.
local len=1 # One letter at a time.
strlen=${#1}
while [ $pos -lt $strlen ]
do
letter=${1:pos:len}
# ^^^^^^^^^^^^ See Chapter 10.1.
play_letter $letter
echo -n "*" # Mark letter just played.
((pos++))
done
}
######### Play the sounds ############
dot() { aplay "$DOT" 2&>/dev/null; }
dash() { aplay "$DASH" 2&>/dev/null; }
######################################
no_args ()
{
declare -a usage
usage=( $0 word1 word2 ... )
echo "Usage:"; echo
echo ${usage[*]}
for index in 0 1 2 3
do
extract_letters ${usage[index]}
usleep $WORDSPACE
echo -n " " # Print space between words.
done
# echo "Usage: $0 word1 word2 ... "
echo; echo
}
# int main()
# {
clear # Clear the terminal screen.
echo " SAM"
echo "Still Another Morse code trainer"
echo " Author: Mendel Cooper"
echo; echo;
if [ -z "$1" ]
then
no_args
echo; echo; echo "$EXIT_MSG"; echo
exit $E_NOARGS
fi
echo; echo "$*" # Print text that will be played.
until [ -z "$1" ]
do
extract_letters $1
shift # On to next word.
usleep $WORDSPACE
echo -n " " # Print space between words.
done
echo; echo; echo "$EXIT_MSG"; echo
exit 0
# }
# Exercises:
# ---------
# 1) Have the script accept either lowercase or uppercase words
#+ as arguments. Hint: Use 'tr' . . .
# 2) Have the script optionally accept input from a text file.

View File

@ -1,9 +1,18 @@
#!/bin/bash #!/bin/bash
# test-suite.sh # test-suite.sh
# A partial Bash compatibility test suite. # A partial Bash compatibility test suite.
# Run this on your version of Bash, or some other shell.
default_option=FAIL # Tests below will fail unless . . .
# Double brackets (test) echo
echo -n "Testing "
sleep 1; echo -n ". "
sleep 1; echo -n ". "
sleep 1; echo ". "
echo
# Double brackets
String="Double brackets supported?" String="Double brackets supported?"
echo -n "Double brackets test: " echo -n "Double brackets test: "
if [[ "$String" = "Double brackets supported?" ]] if [[ "$String" = "Double brackets supported?" ]]
@ -26,14 +35,26 @@ fi
# Arrays # Arrays
test_arr=FAIL test_arr=$default_option # FAIL
Array=( If supports arrays will print PASS ) Array=( If supports arrays will print PASS )
test_arr=${Array[5]} test_arr=${Array[5]}
echo "Array test: $test_arr" echo "Array test: $test_arr"
# Command Substitution
csub_test ()
{
echo "PASS"
}
test_csub=$default_option # FAIL
test_csub=$(csub_test)
echo "Command substitution test: $test_csub"
echo
# Completing this script is an exercise for the reader. # Completing this script is an exercise for the reader.
# Add to the above similar tests for double parentheses, # Add to the above similar tests for double parentheses,
#+ brace expansion, $() command substitution, etc. #+ brace expansion, process substitution, etc.
exit $? exit $?

View File

@ -20,10 +20,10 @@ done
# ... # ...
# USER #30 = bozo # USER #30 = bozo
exit 0 exit $?
# Exercise: # Discussion:
# -------- # ----------
# How is it that an ordinary user (or a script run by same) # How is it that an ordinary user, or a script run by same,
#+ can read /etc/passwd? #+ can read /etc/passwd? (Hint: Check the /etc/passwd file permissions.)
# Isn't this a security hole? Why or why not? # Isn't this a security hole? Why or why not?

View File

@ -1,34 +1,34 @@
#!/bin/bash #!/bin/bash
# wh-loopc.sh: Count to 10 in a "while" loop. # wh-loopc.sh: Count to 10 in a "while" loop.
LIMIT=10 LIMIT=10 # 10 iterations.
a=1 a=1
while [ "$a" -le $LIMIT ] while [ "$a" -le $LIMIT ]
do do
echo -n "$a " echo -n "$a "
let "a+=1" let "a+=1"
done # No surprises, so far. done # No surprises, so far.
echo; echo echo; echo
# +=================================================================+ # +=================================================================+
# Now, repeat with C-like syntax. # Now, we'll repeat with C-like syntax.
((a = 1)) # a=1 ((a = 1)) # a=1
# Double parentheses permit space when setting a variable, as in C. # Double parentheses permit space when setting a variable, as in C.
while (( a <= LIMIT )) # Double parentheses, and no "$" preceding variables. while (( a <= LIMIT )) # Double parentheses,
do do #+ and no "$" preceding variables.
echo -n "$a " echo -n "$a "
((a += 1)) # let "a+=1" ((a += 1)) # let "a+=1"
# Yes, indeed. # Yes, indeed.
# Double parentheses permit incrementing a variable with C-like syntax. # Double parentheses permit incrementing a variable with C-like syntax.
done done
echo echo
# C programmers can feel right at home in Bash. # C and Java programmers can feel right at home in Bash.
exit 0 exit 0

View File

@ -12,7 +12,9 @@ done
exit 0 exit 0
# You may wish to redirect output of this script, like so: # Note: For this to work, you must create a "whatis" database
# ./what.sh >>whatis.db #+ with /usr/sbin/makewhatis.
# or view it a page at a time on stdout, # You may wish to redirect output of this script, like so:
# ./what.sh | less # ./what.sh >>whatis.db
# or view it a page at a time on stdout,
# ./what.sh | less

View File

@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
E_WRONG_DIRECTORY=83 E_WRONG_DIRECTORY=65
clear # Clear screen. clear # Clear the screen.
TargetDirectory=/home/bozo/projects/GreatAmericanNovel TargetDirectory=/home/bozo/projects/GreatAmericanNovel
@ -26,9 +26,10 @@ rm .[A-Za-z0-9]* # Delete dotfiles.
# A filename (`basename`) may contain all characters in the 0 - 255 range, # A filename (`basename`) may contain all characters in the 0 - 255 range,
#+ except "/". #+ except "/".
# Deleting files beginning with weird characters, such as - # Deleting files beginning with weird characters, such as -
#+ is left as an exercise. #+ is left as an exercise. (Hint: rm ./-weirdname or rm -- -weirdname)
echo echo
ls -al # Any files left?
echo "Done." echo "Done."
echo "Old files deleted in $TargetDirectory." echo "Old files deleted in $TargetDirectory."
echo echo

View File

@ -31,7 +31,7 @@ WORDFILE=/usr/share/dict/linux.words # Dictionary file.
# May specify a different word list file # May specify a different word list file
#+ of one-word-per-line format. #+ of one-word-per-line format.
# For example, the "yawl" word-list package, # For example, the "yawl" word-list package,
# http://bash.neuralshortcircuit.com/yawl-0.3.2.tar.gz # http://bash.webofcrafts.net/yawl-0.3.2.tar.gz
wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \ wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \
@ -49,10 +49,10 @@ tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '`
# Finally, "tr Z ' '" converts all those Z's to whitespace, # Finally, "tr Z ' '" converts all those Z's to whitespace,
#+ which will be seen as word separators in the loop below. #+ which will be seen as word separators in the loop below.
# **************************************************************** # ********************************************************************
# Note the technique of feeding the output of 'tr' back to itself, # Note the technique of feeding the output of 'tr' back to itself,
#+ but with different arguments and/or options on each pass. #+ but with different arguments and/or options on each successive pass.
# **************************************************************** # ********************************************************************
for word in $wlist # Important: for word in $wlist # Important:
@ -60,7 +60,6 @@ for word in $wlist # Important:
# "$wlist" does not work. # "$wlist" does not work.
# Why not? # Why not?
do do
strlen=${#word} # String length. strlen=${#word} # String length.
if [ "$strlen" -lt "$MINSTRLEN" ] # Skip over short strings. if [ "$strlen" -lt "$MINSTRLEN" ] # Skip over short strings.
then then
@ -70,8 +69,6 @@ do
grep -Fw $word "$WORDFILE" # Match whole words only. grep -Fw $word "$WORDFILE" # Match whole words only.
# ^^^ # "Fixed strings" and # ^^^ # "Fixed strings" and
#+ "whole words" options. #+ "whole words" options.
done done
exit $? exit $?