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
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
Dated 04/30/12
Current version = 6.4
Dated 08/30/11
http://bash.webofcrafts.net/abs-guide-latest.tar.bz2
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
30 April, 2011
@ -1102,7 +1191,8 @@ Version 5.1, Lingonberry release
20) In "Copyright" appendix:
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
device.

View File

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

View File

@ -265,17 +265,31 @@
</itemizedlist></para>
<para><command>: </command>
<link linkend="nullref">Colon</link>, <firstterm>null</firstterm>
command, equivalent to the
<link linkend="trueref">true</link> Bash builtin
<para><command>:</command> Colon
<itemizedlist>
<listitem><para>
<command>:&gt; <filename>file</filename></command>
<command>:&gt; <filename>filename</filename></command>
<link linkend="ioredirectionref">Truncate file</link>
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>
<para><command>! </command>
<link linkend="notref">Negation operator</link>, inverts <link
linkend="negcond">exit status</link> of a test or command
@ -794,6 +808,8 @@
<!-- ********************** -->
<para><link linkend="arithexpref">Arithmetic expansion</link>
<itemizedlist>
<listitem><para><link linkend="arxs">
<firstterm>exit status</firstterm> of</link></para></listitem>
<listitem><para><link linkend="arithexpvar1">
variations of</link></para></listitem>
</itemizedlist></para>
@ -1190,6 +1206,7 @@
</link>, for handling variables</para>
<para><link linkend="cwsolver">Crossword puzzle solver</link></para>
<para><link linkend="gronsfeld">Cryptography</link></para>
<para>Curly brackets {}
<itemizedlist>
@ -1392,6 +1409,9 @@
references</link></para></listitem>
<listitem><para><link linkend="evalrisk">Risk of
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
<firstterm>eval</firstterm> to select among
variables</link></para></listitem>
@ -1559,6 +1579,9 @@
<listitem><para><link linkend="captureretval">Capturing
the return value</link> of a function
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
must precede</link> first call to function</para></listitem>
<listitem><para><link linkend="exitreturn1">Exit
@ -1586,18 +1609,22 @@
<listitem>
<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>
<para><link linkend="retarray">
Returning an <firstterm>array</firstterm></link> from
a function</para>
<para><link linkend="rvt"><firstterm>return</firstterm>
<para><link linkend="rvt"><firstterm>Return</firstterm>
range limits</link>, workarounds</para>
</listitem>
<listitem><para><link
linkend="fshiftref"><firstterm>shift</firstterm>
linkend="fshiftref"><firstterm>Shift</firstterm>
arguments passed</link> to a function</para></listitem>
<listitem><para><link
linkend="fstrangeref">Unusual function
names</link></para></listitem>
</itemizedlist>
<para>* * *</para>
@ -1685,6 +1712,7 @@
comparison</link> test</para>
<para><link linkend="groffref"><firstterm>groff</firstterm></link>,
text markup and formatting language</para>
<para><link linkend="gronsfeld">Gronsfeld cipher</link></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>
@ -1739,6 +1767,8 @@
<para>Calculating the <link linkend="goldenratio">Golden
Ratio</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
<firstterm>read</firstterm></link></para>
</listitem>
@ -1847,8 +1877,8 @@
<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>,
Emit a sequence of integers. Equivalent to <link
linkend="seqref">seq</link>.
@ -1856,6 +1886,7 @@
<listitem><para><link linkend="jotrandom">Random sequence
generation</link></para></listitem>
</itemizedlist></para>
<para><link linkend="jabh">Just another Bash hacker!</link></para>
<para>* * *</para>
@ -2062,6 +2093,8 @@
<para><link linkend="mathc">Math commands</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
<firstterm>remainder</firstterm> operator
<itemizedlist>
@ -2084,7 +2117,7 @@
</itemizedlist></para>
<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>,
<firstterm>not-equal-to</firstterm> <link
linkend="icomparison1">integer comparison</link> test</para>
@ -2109,6 +2142,20 @@
<para><command>-o </command>
<link linkend="compoundor">Logical OR</link>
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="odref">od</link>, <firstterm>octal
dump</firstterm></para>
@ -2289,10 +2336,18 @@
using</para></listitem>
<listitem><para><link linkend="execperm">Execute permission
lacking</link> for commands within a script</para></listitem>
<listitem><para>
<firstterm>Exit status</firstterm>,
<link linkend="gotchaexitvalanamalies">anomalous</link>
</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
linkend="parchildprobref"><firstterm>Export</firstterm>
problem</link>, <firstterm>child</firstterm> process
@ -2832,7 +2887,13 @@
linkend="jotref">jot</link>.</para>
<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>,
definition of</para>

View File

@ -39,7 +39,7 @@ ex71.sh (line 7)
ex71a.sh (line 8)
ex71b.sh (line 22)
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)
read-r.sh (lines 5, 6, 20, 27)
rnd.sh (comments in lines 38, 55, 64)
@ -104,7 +104,7 @@ qky.sh
line 87
line 113
(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
line 6 (comment)
@ -126,3 +126,6 @@ here-commsub.sh
UseGetOpt.sh: line 4 (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
#+ that is part of the author's "yawl" word list package.
# 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.

View File

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

View File

@ -1,7 +1,7 @@
#!/bin/bash
# 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!).
#
# Encode or decode original Base64 (and also Base64url)
@ -17,9 +17,10 @@
# Reference:
#
# [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 "=" ...
base64_charset=( {A..Z} {a..z} {0..9} + / = )
# Nice illustration of brace expansion.
@ -28,12 +29,12 @@ base64_charset=( {A..Z} {a..z} {0..9} + / = )
#+ original base64.
### base64_charset=( {A..Z} {a..z} {0..9} - _ = )
# Output text width when encoding
# Output text width when encoding
#+ (64 characters, just like openssl output).
text_width=64
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.
printf "${base64_charset[$1]}"; (( width++ ))
(( width % text_width == 0 )) && printf "\n"
@ -41,15 +42,15 @@ function display_base64_char {
function encode_base64 {
# Encode three 8-bit hexadecimal codes into four 6-bit numbers.
# We need two local int array variables:
#  c8[]: to store the codes of the 8-bit characters to encode
# We need two local int array variables:
# c8[]: to store the codes of the 8-bit characters to encode
# c6[]: to store the corresponding encoded values on 6-bit
declare -a -i c8 c6
# Convert hexadecimal to decimal.
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).
(( c6[0] = c8[0] >> 2 ))
(( c6[1] = ((c8[0] & 3) << 4) | (c8[1] >> 4) ))
@ -70,7 +71,7 @@ function encode_base64 {
function decode_base64 {
# 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
declare -a -i c8 c6
@ -86,7 +87,7 @@ function decode_base64 {
c6=( ${c6[*]} ${position} )
done
#  Let's play with bitwise operators
# Let's play with bitwise operators
#+ (4x8-bit into 3x6-bits conversion).
(( c8[0] = (c6[0] << 2) | (c6[1] >> 4) ))
@ -103,9 +104,17 @@ function decode_base64 {
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.
content=$(cat - | xxd -ps -u | sed -r "s/(\w{6})/\1 /g" |
tr -d "\n")
@ -114,16 +123,4 @@ if [ $# -eq 0 ]; then # encode
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

View File

@ -48,6 +48,7 @@ echo # Blank line at beginning of run.
Show_Slots () {
echo; echo
echo -n " "
for i in $( seq $NUMSLOTS ) # Pretty-print array elements.
do
@ -56,7 +57,7 @@ done
echo # Row of slots:
echo " |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|"
echo " ^^"
echo " ||"
echo # Note that if the count within any particular slot exceeds 99,
#+ it messes up the display.
# Running only(!) 500 passes usually avoids this.
@ -86,6 +87,9 @@ done
SHIFT=11 # Why 11, and not 10?
let "POS += $SHIFT" # Shift "zero position" to center.
(( Slots[$POS]++ )) # DEBUG: echo $POS
# echo -n "$POS "
}
@ -115,3 +119,5 @@ exit $?
#+ a scattergram.
# 2) Alter the script to use /dev/urandom instead of $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
#+ the value of PI/4.
#
# The reason for this is that the cannon is actually shooting
#+ only at the upper right-hand quadrant of the square,
# The simplified explanation is that the cannon is actually
#+ shooting only at the upper right-hand quadrant of the square,
#+ i.e., Quadrant I of the Cartesian coordinate plane.
# (The previous explanation was a simplification.)
#
#
# Theoretically, the more shots taken, the better the fit.
# However, a shell script, as opposed to a compiled language
#+ with floating-point math built in, requires a few compromises.
# This tends to lower the accuracy of the simulation.
#+ with floating-point math built in, requires some compromises.
# This decreases the accuracy of the simulation.
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.
# 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
# Actual 9-place value of PI, for comparison purposes.
@ -68,13 +68,13 @@ EOF
)
# Setting "scale" to zero rounds down result to integer value,
#+ a necessary compromise in this script.
# This decreases the accuracy of the simulation.
# It decreases the accuracy of this simulation.
}
# ==========================================================
# main() {
# "Main" code block, mimmicking a C-language main() function.
# "Main" code block, mimicking a C-language main() function.
# Initialize variables.
shots=0
@ -119,9 +119,9 @@ done
echo
echo "After $shots shots, PI looks like approximately $Pi"
# 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% . . .
#+ a pretty good rough approximation.
#+ a pretty fair rough approximation.
error=$(echo "scale=9; $Pi - $M_PI" | bc)
pct_error=$(echo "scale=2; 100.0 * $error / $M_PI" | bc)
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
#+ an application as complex and computation-intensive as a simulation.

View File

@ -1,7 +1,7 @@
#!/bin/bash
# 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' ...
i386 ) echo "80386-based machine";;
i486 ) echo "80486-based machine";;

View File

@ -11,7 +11,7 @@
# 6) NUMBER &lt;-- result
# 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,
#+ eventually settles down to repeating "4,2,1..." cycles,
#+ even after fluctuating through a wide range of values.
@ -29,7 +29,7 @@ h=${1:-$$} # Seed.
#+ if not specified as command-line arg.
echo
echo "C($h) --- $MAX_ITERATIONS Iterations"
echo "C($h) -*- $MAX_ITERATIONS Iterations"
echo
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
#+ any data that is to be treated in files of a given name pattern in a
#+ directory. There are several machines that access this directory, and
#+ I want to distribute the work over these different boxen. Then I
#+ usually nohup something like the following on every box:
#+ any data that is to be treated in files of a given name pattern
#+ in a directory. There are several machines that access
#+ this directory, and I want to distribute the work over these
#+ different boxen.
# Then I usually nohup something like the following on every box:
while true
do
@ -26,6 +27,8 @@ do
break
done
exit 0
# The details, in particular the sleep N, are particular to my
#+ 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.
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
# 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

View File

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

View File

@ -274,7 +274,7 @@ IndexList()
The key (no pun intended) to a Unified Content File System (UCFS)
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.
This version uses the md5sum program to generate a 128 bit checksum

View File

@ -1,8 +1,6 @@
#!/bin/bash
# escaped.sh: escaped characters
echo; echo
#############################################################
### First, let's show some basic escaped-character usage. ###
#############################################################
@ -41,22 +39,19 @@ echo "=============="
# The $'\X' construct makes the -e option unnecessary.
echo; echo "NEWLINE AND BEEP"
echo; echo "NEWLINE and (maybe) BEEP"
echo $'\n' # Newline.
echo $'\a' # Alert (beep).
# May only flash, not beep, depending on terminal.
echo "---------------"
echo "QUOTATION MARKS"
echo "---------------"
echo; echo; echo
# Here we have seen $'\nnn" string expansion.
# We have seen $'\nnn" string expansion, and now . . .
# =================================================================== #
# Version 2 of Bash introduced the $'\nnn' string expansion construct.
# =================================================================== #
echo "Introducing the \$\' ... \' string-expansion construct!"
echo
echo "Introducing the \$\' ... \' string-expansion construct . . . "
echo ". . . featuring more quotation marks."
echo $'\t \042 \t' # Quote (") framed by tabs.
# 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.
# Earlier Bash versions allowed '\x022'.
echo "==============="
echo
# Assigning ASCII characters 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
@ -87,12 +80,12 @@ echo
ABC=$'\101\102\103\010' # 101, 102, 103 are octal A, B, C.
echo $ABC
echo; echo
echo
escape=$'\033' # 033 is octal for escape.
echo "\"escape\" echoes as $escape"
# no visible output.
echo; echo
echo
exit 0

View File

@ -3,9 +3,9 @@
# View gzipped files with 'more' filter.
E_NOARGS=65
E_NOTFOUND=66
E_NOTGZIP=67
E_NOARGS=85
E_NOTFOUND=86
E_NOTGZIP=87
if [ $# -eq 0 ] # same effect as: if [ -z "$1" ]
# $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"
# Thanks, S.C.
# Or even . . .
# cat "$1" | tr a-z A-Z
# Or dozens of other ways . . .
exit 0
# Exercise:
# Rewrite this script to give the option of changing a file
#+ to *either* upper or lowercase.
# Hint: Use either the "case" or "select" command.

View File

@ -4,18 +4,18 @@
# Script by Stephane Chazelas.
# Somewhat modified by ABS Guide author.
infile=$0 # This script.
outfile=log.txt # Output file left behind.
n=3
p=5
infile=$0 # This script.
outfile=log.txt # Output file left behind.
n=8
p=11
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
# Echoes "hello world" vertically.
echo -n "hello vertical world" | dd cbs=1 conv=unblock 2> /dev/null
# Echoes "hello vertical world" vertically downward.
# Why? A newline follows each character dd emits.
exit 0
exit $?

View File

@ -7,6 +7,7 @@
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
#+ and display "From" in color.
TARGETSTR="^From" # "From" at beginning of line.
@ -20,5 +21,5 @@ done
exit $?
# Might wish to pipe the output of this script to 'more' or
#+ redirect it to a file . . .
# You might wish to pipe the output of this script to 'more'
#+ 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
Download the archived set of scripts
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

View File

@ -1,5 +1,7 @@
#!/bin/bash
# life.sh: "Life in the Slow Lane"
# Author: Mendel Cooper
# License: GPL3
# Version 0.2: Patched by Daniel Albers
#+ to allow non-square grids as input.
@ -11,8 +13,8 @@
# --------------------------------------------------------------------- #
# 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." #
# 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. #
@ -23,7 +25,7 @@
# #
# 2) A living cell with either 2 or 3 living neighbors remains alive. #
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 #
# 4) All other cases result in a dead cell for the next generation. #
# ##################################################################### #
@ -56,13 +58,13 @@ ALIVE1=.
DEAD1=_
# 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 slow execution).
#+ but a large grid will slow down execution).
ROWS=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.
# Adjust this upwards
@ -70,7 +72,7 @@ GENERATIONS=10 # How many generations to cycle through.
NONE_ALIVE=85 # Exit status on premature bailout,
#+ if no cells left alive.
DELAY=2 # Pause between generations, etc.
DELAY=2 # Pause between generations.
TRUE=0
FALSE=1
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?
@ -179,7 +181,7 @@ IsAlive () # Test whether cell is alive.
return $ALIVE
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" ]
then
if [ ${array[$t_top]} = "$ALIVE1" ] # Redundancy here.
then # Can be optimized?
then # Can it be optimized?
let "count += 1"
fi
fi
@ -270,7 +272,7 @@ array=( `echo "$1"` ) # Convert passed arg to array.
while [ "$i" -lt "$cells" ]
do
IsAlive "$1" $i ${array[$i]} # Is cell alive?
IsAlive "$1" $i ${array[$i]} # Is the cell alive?
if [ $? -eq "$ALIVE" ]
then # If alive, then
array[$i]=. #+ represent the cell as a period.
@ -281,8 +283,8 @@ do
done
# let "generation += 1" # Increment generation count.
# Why was the above line commented out?
# let "generation += 1" # Increment generation count.
### Why was the above line commented out?
# Set variable to pass as parameter to "display" function.
@ -304,6 +306,7 @@ fi #+ if no live cells.
# =========================================================
# main ()
# {
# Load initial array with contents of startup file.
initial=( `cat "$startfile" | sed -e '/#/d' | tr -d '\n' |\
@ -358,6 +361,7 @@ done
# ==============================================================
echo
# }
exit 0 # CEOF:EOF
@ -381,4 +385,4 @@ exit 0 # CEOF:EOF
#+ in the script for an altered grid size.
#
# 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
# Arithmetic
echo "incr(22)" | m4 # 23
echo "eval(99 / 3)" | m4 # 33
var=99
echo "incr($var)" | m4 # 100
echo "eval($var / 3)" | m4 # 33
exit

View File

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

View File

@ -62,6 +62,9 @@ progname ()
else
echo "Error! No input." # Mandatory input.
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
echo -n " \"$section\"">>$savefile # Append, always append.
@ -139,5 +142,6 @@ end # ... exit not needed.
# Exercise (difficult): Fix this!
# 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.

View File

@ -6,8 +6,8 @@
#+ "mcalc" (mortgage calculator) package,
#+ by Jeff Schmidt
#+ and
#+ Mendel Cooper (yours truly, the author of the ABS Guide).
# http://www.ibiblio.org/pub/Linux/apps/financial/mcalc-1.6.tar.gz [15k]
#+ Mendel Cooper (yours truly, the ABS Guide author).
# http://www.ibiblio.org/pub/Linux/apps/financial/mcalc-1.6.tar.gz
echo
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
val1=`multiply $mult1 $mult2`
echo "$mult1 X $mult2 = $val1"
# 387820813
# Assigns stdout (echo) of function to the variable val1.
echo "$mult1 X $mult2 = $val1" # 387820813
mult1=25; mult2=5; mult3=20
val2=`multiply $mult1 $mult2 $mult3`
echo "$mult1 X $mult2 X $mult3 = $val2"
# 2500
echo "$mult1 X $mult2 X $mult3 = $val2" # 2500
mult1=188; mult2=37; mult3=25; mult4=47
val3=`multiply $mult1 $mult2 $mult3 $mult4`
echo "$mult1 X $mult2 X $mult3 X $mult4 = $val3"
# 8173300
echo "$mult1 X $mult2 X $mult3 X $mult4 = $val3" # 8173300
exit 0

View File

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

View File

@ -3,6 +3,8 @@
# Requires Bash, version -ge 4.2.
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.
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.
echo
# See also neg-offset.sh.

View File

@ -1,21 +1,26 @@
#!/bin/bash
# Bash, version -ge 4.2
# Negative length-index in substring extraction.
# Important: This changes the interpretation of this construct!
# Important: It changes the interpretation of this construct!
stringZ=abcABC123ABCabc
echo ${stringZ} # abcABC123ABCabc
# Position within string: 0123456789.....
echo ${stringZ:2:3} # cAB
# Count 2 chars forward from string beginning, and extract 3 chars.
# ${string:position:length}
# So far, nothing new, but now ...
# abcABC123ABCabc
# Position within string: 0123....6543210
echo ${stringZ:3:-6} # ABC123
# ^
# Index 3 chars forward from beginning and 6 chars backward from end,
#+ and extract everything in between.
# ${string:offset-from-front:offset-from-end}
# 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
#+ firewire HDD using rsync and ssh.
# (Script should work with USB-connected device (see lines 40-43).
# It then rotates the backups.
# Run it via cron every night at 5am.
# 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.
# NO trailing slash!
# 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.
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.

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
array0[${#array0[@]}]="$REPLY"
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[@]}"

View File

@ -13,7 +13,7 @@ WLIST=/usr/share/dict/word.lst
# ^^^^^^^^ Word list file found here.
# ASCII word list, one word per line, UNIX format.
# A suggested list is the script author's "yawl" word list package.
# http://bash.neuralshortciruit.com/yawl-0.3.2.tar.gz
# http://bash.webofcrafts.net/yawl-0.3.2.tar.gz
# or
# http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz
@ -462,4 +462,4 @@ exit $?
# 7) Fix bugs!!!
# 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
# test-suite.sh
# 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?"
echo -n "Double brackets test: "
if [[ "$String" = "Double brackets supported?" ]]
@ -26,14 +35,26 @@ fi
# Arrays
test_arr=FAIL
test_arr=$default_option # FAIL
Array=( If supports arrays will print PASS )
test_arr=${Array[5]}
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.
# Add to the above similar tests for double parentheses,
#+ brace expansion, $() command substitution, etc.
#+ brace expansion, process substitution, etc.
exit $?

View File

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

View File

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

View File

@ -12,7 +12,9 @@ done
exit 0
# You may wish to redirect output of this script, like so:
# ./what.sh >>whatis.db
# or view it a page at a time on stdout,
# ./what.sh | less
# Note: For this to work, you must create a "whatis" database
#+ with /usr/sbin/makewhatis.
# You may wish to redirect output of this script, like so:
# ./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
E_WRONG_DIRECTORY=83
E_WRONG_DIRECTORY=65
clear # Clear screen.
clear # Clear the screen.
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,
#+ except "/".
# 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
ls -al # Any files left?
echo "Done."
echo "Old files deleted in $TargetDirectory."
echo

View File

@ -31,7 +31,7 @@ WORDFILE=/usr/share/dict/linux.words # Dictionary file.
# May specify a different word list file
#+ of one-word-per-line format.
# For example, the "yawl" word-list package,
# http://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 | \
@ -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,
#+ which will be seen as word separators in the loop below.
# ****************************************************************
# ********************************************************************
# 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:
@ -60,7 +60,6 @@ for word in $wlist # Important:
# "$wlist" does not work.
# Why not?
do
strlen=${#word} # String length.
if [ "$strlen" -lt "$MINSTRLEN" ] # Skip over short strings.
then
@ -70,8 +69,6 @@ do
grep -Fw $word "$WORDFILE" # Match whole words only.
# ^^^ # "Fixed strings" and
#+ "whole words" options.
done
exit $?