From 189f9f596e4c0ffdfbeb1afb4e2acc71b4249c2a Mon Sep 17 00:00:00 2001 From: gferg <> Date: Mon, 29 Aug 2011 23:59:19 +0000 Subject: [PATCH] updated --- LDP/guide/docbook/abs-guide/Change.log | 100 ++- LDP/guide/docbook/abs-guide/Du.sh | 2 +- LDP/guide/docbook/abs-guide/INDEX00.sgml | 83 ++- LDP/guide/docbook/abs-guide/README | 7 +- LDP/guide/docbook/abs-guide/abs-guide.sgml | 676 +++++++++++++----- LDP/guide/docbook/abs-guide/agram.sh | 2 +- LDP/guide/docbook/abs-guide/agram2.sh | 2 +- LDP/guide/docbook/abs-guide/base64.sh | 45 +- LDP/guide/docbook/abs-guide/brownian.sh | 8 +- LDP/guide/docbook/abs-guide/cannon.sh | 22 +- LDP/guide/docbook/abs-guide/case-cmd.sh | 2 +- LDP/guide/docbook/abs-guide/collatz.sh | 4 +- .../docbook/abs-guide/continue-n.example | 11 +- LDP/guide/docbook/abs-guide/cw-solver.sh | 2 +- LDP/guide/docbook/abs-guide/dereference.sh | 2 +- LDP/guide/docbook/abs-guide/directory-info.sh | 2 +- LDP/guide/docbook/abs-guide/escaped.sh | 23 +- LDP/guide/docbook/abs-guide/ex14.sh | 6 +- LDP/guide/docbook/abs-guide/ex49.sh | 5 + LDP/guide/docbook/abs-guide/exercising-dd.sh | 18 +- LDP/guide/docbook/abs-guide/from.sh | 5 +- LDP/guide/docbook/abs-guide/gronsfeld.bash | 147 ++++ LDP/guide/docbook/abs-guide/is_spammer.bash | 2 +- LDP/guide/docbook/abs-guide/life.sh | 34 +- LDP/guide/docbook/abs-guide/m4.sh | 5 +- LDP/guide/docbook/abs-guide/makedict.sh | 15 +- LDP/guide/docbook/abs-guide/maned.sh | 6 +- LDP/guide/docbook/abs-guide/monthlypmt.sh | 4 +- LDP/guide/docbook/abs-guide/multiplication.sh | 10 +- LDP/guide/docbook/abs-guide/names.data | 4 +- LDP/guide/docbook/abs-guide/neg-array.sh | 4 + LDP/guide/docbook/abs-guide/neg-offset.sh | 9 +- LDP/guide/docbook/abs-guide/nightly-backup.sh | 2 + LDP/guide/docbook/abs-guide/progress-bar2.sh | 31 + LDP/guide/docbook/abs-guide/psub.bash | 2 + LDP/guide/docbook/abs-guide/qky.sh | 4 +- LDP/guide/docbook/abs-guide/sam.sh | 157 ++++ LDP/guide/docbook/abs-guide/test-suite.sh | 27 +- LDP/guide/docbook/abs-guide/userlist.sh | 10 +- LDP/guide/docbook/abs-guide/wh-loopc.sh | 14 +- LDP/guide/docbook/abs-guide/what.sh | 10 +- LDP/guide/docbook/abs-guide/wipedir.sh | 7 +- LDP/guide/docbook/abs-guide/wstrings.sh | 11 +- 43 files changed, 1179 insertions(+), 363 deletions(-) create mode 100644 LDP/guide/docbook/abs-guide/gronsfeld.bash create mode 100644 LDP/guide/docbook/abs-guide/progress-bar2.sh create mode 100644 LDP/guide/docbook/abs-guide/sam.sh diff --git a/LDP/guide/docbook/abs-guide/Change.log b/LDP/guide/docbook/abs-guide/Change.log index 5dbf791d..eceaef93 100644 --- a/LDP/guide/docbook/abs-guide/Change.log +++ b/LDP/guide/docbook/abs-guide/Change.log @@ -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. diff --git a/LDP/guide/docbook/abs-guide/Du.sh b/LDP/guide/docbook/abs-guide/Du.sh index 766c5ac2..2a279823 100644 --- a/LDP/guide/docbook/abs-guide/Du.sh +++ b/LDP/guide/docbook/abs-guide/Du.sh @@ -1,7 +1,7 @@ #!/bin/bash # Du.sh: DOS to UNIX text file converter. -E_WRONGARGS=65 +E_WRONGARGS=85 if [ -z "$1" ] then diff --git a/LDP/guide/docbook/abs-guide/INDEX00.sgml b/LDP/guide/docbook/abs-guide/INDEX00.sgml index b8cd36dc..3b5c3b0d 100644 --- a/LDP/guide/docbook/abs-guide/INDEX00.sgml +++ b/LDP/guide/docbook/abs-guide/INDEX00.sgml @@ -265,17 +265,31 @@ - : - Colon, null - command, equivalent to the - true Bash builtin + + : Colon + - :> file + :> filename Truncate file to zero length + + null + command, equivalent to the + true Bash + builtin + + Used in an anonymous + here document + + Used as a function + name + + + ! Negation operator, inverts exit status of a test or command @@ -794,6 +808,8 @@ Arithmetic expansion + + exit status of variations of @@ -1190,6 +1206,7 @@ , for handling variables Crossword puzzle solver + Cryptography Curly brackets {} @@ -1392,6 +1409,9 @@ references Risk of using + Using + eval to convert array + elements into a command list Using eval to select among variables @@ -1559,6 +1579,9 @@ Capturing the return value of a function using echo + Colon + as function name Definition must precede first call to function Exit @@ -1586,18 +1609,22 @@ return - Multiple return values from a function, + Multiple return values from + a function, example script Returning an array from a function - return + Return range limits, workarounds shift + linkend="fshiftref">Shift arguments passed to a function + Unusual function + names * * * @@ -1685,6 +1712,7 @@ comparison test groff, text markup and formatting language + Gronsfeld cipher $GROUPS, Groups user belongs to gzip, compression utility @@ -1739,6 +1767,8 @@ Calculating the Golden Ratio Prepending text + As the stdin of a + loop Using read @@ -1847,8 +1877,8 @@ * * * - Job IDs, table + Job IDs, table jot, Emit a sequence of integers. Equivalent to seq. @@ -1856,6 +1886,7 @@ Random sequence generation + Just another Bash hacker! * * * @@ -2062,6 +2093,8 @@ Math commands Meta-meaning + Morse code training script + Modulo, arithmetic remainder operator @@ -2084,7 +2117,7 @@ nc, netcat, - a toolkit for TCP and UDP ports + a network toolkit for TCP and UDP ports -ne, not-equal-to integer comparison test @@ -2109,6 +2142,20 @@ -o Logical OR compound comparison test + + Obfuscation + + Colon + as function name + Homework assignment + Just another Bash + hacker! + + + + octal, base-8 numbers od, octal dump @@ -2289,10 +2336,18 @@ using Execute permission lacking for commands within a script + Exit status, anomalous + + + Exit status + of arithmetic expression not + equivalent to an error code + + Export problem, child process @@ -2832,7 +2887,13 @@ linkend="jotref">jot. set, - Change value of internal script variables + Change value of internal script variables + + set -u, + Abort script with error message if attempting to use + an undeclared variable. + + Shell script, definition of diff --git a/LDP/guide/docbook/abs-guide/README b/LDP/guide/docbook/abs-guide/README index 68cd06f5..cac33d85 100644 --- a/LDP/guide/docbook/abs-guide/README +++ b/LDP/guide/docbook/abs-guide/README @@ -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: "\&" --> &) +m4.sh (line 8: "\&" --> \&) 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) diff --git a/LDP/guide/docbook/abs-guide/abs-guide.sgml b/LDP/guide/docbook/abs-guide/abs-guide.sgml index 827060fe..e2c71f1a 100644 --- a/LDP/guide/docbook/abs-guide/abs-guide.sgml +++ b/LDP/guide/docbook/abs-guide/abs-guide.sgml @@ -352,6 +352,7 @@ + @@ -380,7 +381,9 @@ + + @@ -404,21 +407,14 @@ - 6.3. - 30 Apr 2011 + 6.4 + 30 Aug 2011 978-1-4357-5219-1 - - 6.1 - 30 Sep 2009 - mc - 'BUFFALOBERRY' release: Minor Update. - - 6.2 17 Mar 2010 @@ -433,6 +429,13 @@ 'SWOZZLEBERRY' release + + 6.4 + 30 Aug 2011 + mc + 'VORTEXBERRY' release + + @@ -497,8 +500,8 @@ No programming language is perfect. There is not even a single - best language; there are only languages well suited or perhaps poorly - suited for particular purposes. + best language; there are only languages well suited or perhaps + poorly suited for particular purposes. --Herbert Mayer @@ -530,11 +533,11 @@
- - In the 1970s, the BASIC language enabled anyone reasonably computer proficient - to write programs on an early generation of microcomputers. Decades later, the Bash - scripting language enables anyone with a rudimentary knowledge of Linux or UNIX to do the same - on much more powerful machines. + In the 1970s, the BASIC language enabled anyone reasonably + computer proficient to write programs on an early generation of + microcomputers. Decades later, the Bash scripting language enables + anyone with a rudimentary knowledge of Linux or UNIX to do the same + on much more powerful machines.
@@ -543,8 +546,8 @@ A shell script is a quick-and-dirty method of prototyping a complex application. Getting even a limited subset of the functionality to work in a script is often a useful - first stage in project development. This way, the structure - of the application can be tested and played with, and the + first stage in project development. In this way, the structure + of the application can be tested and tinkered with, and the major pitfalls found before proceeding to the final coding in C, C++, Java, Perl, @@ -579,7 +582,8 @@ Although recursion is possible in a shell script, it tends to be slow and its implementation is often - an ugly kludge. + an ugly kludge. + ...) @@ -620,9 +624,11 @@
Need to generate / manipulate graphics or GUIs - Need direct access to system hardware + Need direct access to system hardware or + external peripherals - Need port or socket I/O + Need port or socket + I/O Need to use libraries or interface with legacy code @@ -646,8 +652,15 @@ - We will be using Bash, an acronym for - Bourne-Again shell and a pun on Stephen Bourne's + We will be using Bash, an acronym + + An acronym + is a word formed by pasting together the initial letters of the + words in a tongue-tripping phrase. This is a harmful + and subversive practice that surely deserves severe punishment. + + + for Bourne-Again shell and a pun on Stephen Bourne's now classic Bourne shell. Bash has become a de facto standard for shell scripting on most flavors of UNIX. Most of the principles this @@ -673,11 +686,11 @@ in the source archive (scriptname.sh or scriptname.bash), - By convention, user-written shell scripts that are - Bourne shell compliant generally take a name with a - .sh extension. System scripts, such as - those found in /etc/rc.d, - do not conform to this nomenclature. + By convention, user-written shell scripts + that are Bourne shell compliant generally take a name with a + .sh extension. System scripts, such as + those found in /etc/rc.d, + do not conform to this nomenclature. give them execute permission (chmod u+rx scriptname), @@ -710,10 +723,10 @@ --Larry Wall - In the simplest case, a script is nothing more than a list of system - commands stored in a file. At the very least, this saves the - effort of retyping that particular sequence of commands each time - it is invoked. + In the simplest case, a script is nothing more than a list + of system commands stored in a file. At the very least, this saves + the effort of retyping that particular sequence of commands each + time it is invoked. <firstterm>cleanup</firstterm>: A script to clean up log @@ -734,8 +747,8 @@ script &ex1a; - Now that's beginning to look like a real script. But we can - go even farther . . . + Now that's beginning to look like a real + script. But we can go even farther . . . <firstterm>cleanup</firstterm>: An enhanced @@ -759,7 +772,7 @@ <primary>#!</primary> </indexterm> #!</token>) - <footnote><para>Also seen in the literature as + <footnote><para>More commonly seen in the literature as <firstterm>she-bang</firstterm> or <firstterm>sh-bang</firstterm>. This derives from the concatenation of the tokens <firstterm>sharp</firstterm> (<token>#</token>) and @@ -1549,7 +1562,9 @@ fi</programlisting> <para><programlisting>: ${username=`whoami`} # ${username=`whoami`} Gives an error without the leading : -# unless "username" is a command or builtin...</programlisting> +# unless "username" is a command or builtin... + +: ${1?"Usage: $0 ARGUMENT"} # From "usage-message.sh example script.</programlisting> </para> <para>Provide a placeholder where a command is expected in a @@ -1598,7 +1613,7 @@ fi</programlisting> <programlisting>: This is a comment that generates an error, ( if [ $x -eq 3] ).</programlisting> </para> - <para>The <quote><token>:</token></quote> also serves as a <link + <para>The <quote><token>:</token></quote> serves as a <link linkend="fieldref">field</link> separator, in <link linkend="datafilesref1"><filename>/etc/passwd</filename></link>, @@ -1607,6 +1622,22 @@ fi</programlisting> <computeroutput>/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games</computeroutput></screen> </para> + <para><anchor id="colonfname"></para> + <para>A <firstterm>colon</firstterm> is <link + linkend="fstrangeref">acceptable as a function name</link>. + <programlisting>:() +{ + echo "The name of this function is "$FUNCNAME" + # Why use a colon as a function name? + # It's a way of obfuscating your code. +} + +: + +# The name of this function is :</programlisting> + + This is not <link linkend="portabilityissues">portable</link> + behavior, and therefore not a recommended practice. </para> </listitem> @@ -1918,7 +1949,7 @@ echo $var2 # 23skidoo</programlisting> <command>I</command>nterchange. This is a system for encoding text characters (alphabetic, numeric, and a limited set of symbols) - as numbers that can be stored and manipulated by + as 7-bit numbers that can be stored and manipulated by computers. Many of the ASCII characters are represented on a standard keyboard.</para></footnote> @@ -3387,7 +3418,18 @@ echo; echo # a=$'\010\010' # a=$'\b\b' # a=$'\x08\x08' -# But, this does not change the results.</programlisting> +# But, this does not change the results. + +######################################## + +# Now, try this. + +rubout="^H^H^H^H^H" # 5 x Ctl-H. + +echo -n "12345678" +sleep 2 +echo -n "$rubout" +sleep 2</programlisting> </para> </listitem> @@ -5102,11 +5144,12 @@ echo $? # 0 <listitem> <para><anchor id="dblparenstst"></para> <para>The <link linkend="dblparens">(( ... ))</link> and <link - linkend="letref">let ...</link> constructs also return an - exit status, according to whether the arithmetic expressions - they evaluate expand to a non-zero value. These <link - linkend="arithexpref">arithmetic-expansion</link> constructs - may therefore be used to perform <link + linkend="letref">let ...</link> constructs return an + <link linkend="exitstatusref">exit status</link>, + <emphasis>according to whether the arithmetic expressions they + evaluate expand to a non-zero value</emphasis>. These + <link linkend="arithexpref">arithmetic-expansion</link> + constructs may therefore be used to perform <link linkend="icomparison1">arithmetic comparisons</link>.</para> <para> @@ -5140,6 +5183,17 @@ echo $? # 0 *** # The "let" construct returns the same exit status #+ as the double-parentheses arithmetic expansion.</programlisting> </para> + + <caution><para><anchor id="arxs">Again, note that the + <firstterm>exit status</firstterm> of an arithmetic expression + is <emphasis>not</emphasis> an error value. + <programlisting>var=-2 && (( var+=2 )) +echo $? # 1 + +var=-2 && (( var+=2 )) && echo $var + # Will not echo $var!</programlisting> + </para></caution> + </listitem> <listitem> @@ -5869,6 +5923,14 @@ echo "Input" | show_input_type # PIPE <para><anchor id="equalsignref"></para> <para>is equal to</para> <para><userinput>if [ "$a" = "$b" ]</userinput></para> + + <caution><para>Note the <link + linkend="whitespaceref">whitespace</link> + framing the <command>=</command>.</para> + <para><userinput>if [ "$a"="$b" ]</userinput> is + <emphasis>not</emphasis> equivalent to the + above.</para></caution> + </listitem> </varlistentry> @@ -9430,7 +9492,17 @@ echo ${stringZ#a*C} # 123ABCabc # Strip out shortest match between 'a' and 'C'. echo ${stringZ##a*C} # abc -# Strip out longest match between 'a' and 'C'.</programlisting> +# Strip out longest match between 'a' and 'C'. + + + +# You can parameterize the substrings. + +X='a*C' + +echo ${stringZ#$X} # 123ABCabc +echo ${stringZ##$X} # abc + # As above.</programlisting> </para> </listitem> </varlistentry> @@ -10866,7 +10938,8 @@ done <listitem> <para>The <command>case</command> construct is the shell - scripting analog to <firstterm>switch</firstterm> in C/C++. + scripting analog to <replaceable>switch</replaceable> + in <command>C/C++</command>. It permits branching to one of a number of code blocks, depending on condition tests. It serves as a kind of shorthand for multiple <token>if/then/else</token> @@ -10892,9 +10965,25 @@ done since word splitting does not take place.</para> </listitem> <listitem> + <para><anchor id="caseparen">Each test line - ends with a right paren <token>)</token>.</para> + ends with a right paren <command>)</command>. + + <footnote><para>Pattern-match lines may also <emphasis>start</emphasis> + with a <command>(</command> left paren to give the layout + a more structured appearance.</para> + <para><programlisting>case $( arch ) in # $( arch ) returns machine architecture. + ( i386 ) echo "80386-based machine";; +# ^ ^ + ( i486 ) echo "80486-based machine";; + ( i586 ) echo "Pentium-based machine";; + ( i686 ) echo "Pentium2+-based machine";; + ( * ) echo "Other type of machine";; +esac</programlisting></para></footnote> + </para> + </listitem> + <listitem><para>Each condition block ends with a <emphasis>double</emphasis> semicolon <token>;;</token>.</para> @@ -12712,6 +12801,10 @@ eval eval echo $a # d <programlisting>&rot14;</programlisting> </example> + <para><xref linkend="samorse"> uses + <firstterm>eval</firstterm> to convert <link + linkend="arrayref">array</link> elements into a command + list.</para> <para>The <firstterm>eval</firstterm> command occurs in the older version of <link linkend="ivrref">indirect @@ -13958,8 +14051,9 @@ wait</programlisting> class="directory">/usr/share/doc/bash-?.??/functions</filename> directory.</para> <para>Note that the <option>-f</option> option to - <command>enable</command> is not portable to all - systems.</para> + <command>enable</command> is not <link + linkend="portabilityissues">portable</link> to all + systems.</para> </footnote>. </para> @@ -16366,6 +16460,18 @@ tr -d 0-9 <filename <programlisting>&cryptoquote;</programlisting> </example> + <para><anchor id="jabh">Of course, <firstterm>tr</firstterm> + lends itself to <firstterm>code + obfuscation</firstterm>.</para> + + <para><programlisting>#!/bin/bash +# jabh.sh + +x="wftedskaebjgdBstbdbsmnjgz" +echo $x | tr "a-z" "oh, turtleneck Phrase Jar!" + +# Based on the Wikipedia "Just another Perl hacker" article.</programlisting></para> + <para><anchor id="trvariants"></para> <sidebar><title><firstterm>tr</firstterm> variants @@ -19642,14 +19748,13 @@ wget -c ftp://ftp.xyz25.net/bozofiles/filename.tar.bz2 Bash can't handle floating point calculations, and it lacks operators for certain important mathematical - functions. Fortunately, bc comes to + functions. Fortunately, bc gallops to the rescue. Not just a versatile, arbitrary precision calculation utility, bc offers many of the facilities of - a programming language. - - bc has a syntax vaguely resembling C. + a programming language. It has a syntax vaguely resembling + C. Since it is a fairly well-behaved UNIX utility, and may therefore be used in a pipe, @@ -19739,12 +19844,20 @@ LIMIT_STRING The dc (desk calculator) utility is stack-oriented - and uses RPN (Reverse Polish Notation). Like - bc, it has much of the power of a - programming language. + and uses RPN (Reverse Polish Notation). + Like bc, it has much of the power of + a programming language. + + Similar to the procedure with bc, + echo a command-string + to dc. - echo "7 8 * p" | dc # 56 + echo "[Printing a string ... ]P" | dc +# The P command prints the string between the preceding brackets. + +# And now for some simple arithmetic. +echo "7 8 * p" | dc # 56 # Pushes 7, then 8 onto the stack, #+ multiplies ("*" operator), then prints the result ("p" operator). @@ -19758,7 +19871,7 @@ LIMIT_STRING &hexconvert; - Studying the info page for + Studying the info page for dc is a painful path to understanding its intricacies. There seems to be a small, select group of dc wizards who delight in showing off @@ -19774,7 +19887,8 @@ LIMIT_STRING dc <<< 10k5v1+2/p # 1.6180339887 # ^^^ Feed operations to dc using a Here String. # ^^^ Pushes 10 and sets that as the precision (10k). -# ^^ Pushes 5 and takes its square root (5v, v = square root). +# ^^ Pushes 5 and takes its square root +# (5v, v = square root). # ^^ Pushes 1 and adds it to the running total (1+). # ^^ Pushes 2 and divides the running total by that (2/). # ^ Pops and prints the result (p) @@ -20297,22 +20411,23 @@ Mixed.msg BOZO dd - This is the somewhat obscure and much feared data - duplicator command. Originally a utility - for exchanging data on magnetic tapes between UNIX - minicomputers and IBM mainframes, this command still - has its uses. The dd command simply - copies a file (or stdin/stdout), but - with conversions. Possible - conversions are ASCII/EBCDIC, + Though this somewhat obscure and much feared + data duplicator + command originated as a utility for exchanging + data on magnetic tapes between UNIX minicomputers + and IBM mainframes, it still has its uses. + The dd command simply copies a + file (or stdin/stdout), but with + conversions. Possible conversions + include ASCII/EBCDIC, EBCDIC (pronounced ebb-sid-ick) is an acronym for Extended - Binary Coded Decimal Interchange Code. This is an IBM - data format no longer in much use. A bizarre - application of the option - of dd is as a quick 'n easy, but - not very secure text file encoder. + Binary Coded Decimal Interchange Code, an obsolete + IBM data format. A bizarre application of + the option of + dd is as a quick 'n easy, but not + very secure text file encoder. cat $file | dd conv=swab,ebcdic > $file_encrypted # Encode (looks like gibberish). # Might as well switch bytes (swab), too, for a little extra obscurity. @@ -21815,6 +21930,9 @@ getenv("DF_BLOCK_SIZE") = NULL Thu, 31 Mar 2005 15:41:35 -0700 + A real-life usage + example. + Checking a remote server for <firstterm>identd</firstterm> @@ -24386,15 +24504,16 @@ print "even when I don't know where to find Perl.\n"; root). Do a simulated run with the flags (sh -vn scriptname). Add extensive - comments. Change the action commands to - echos. + comments. Change the commands to echos. Exercise 2 Look at some of the more complex scripts in - /etc/rc.d/init.d. See if - you can understand parts of them. Follow the above procedure - to analyze them. For some additional insight, you might also - examine the file sysvinitfiles in /etc/rc.d/init.d. + Try to understand at least portions of them. Follow + the above procedure to analyze them. For some + additional insight, you might also examine the + file sysvinitfiles in /usr/share/doc/initscripts-?.??, which is part of the initscripts documentation. @@ -25319,9 +25438,9 @@ InputComesFromHERE A limit string delineates (frames) - the command list. The special symbol << designates + the command list. The special symbol << precedes the limit string. This has the effect of redirecting the output - of a file into the stdin of the program + of a command block into the stdin of the program or command. It is similar to interactive-program < command-file, where command-file contains @@ -25330,10 +25449,10 @@ InputComesFromHERE command #2 ... - The here document alternative looks - like this: + The here document equivalent looks + like this: - interactive-program <<LimitString + interactive-program <<LimitString command #1 command #2 ... @@ -25700,6 +25819,21 @@ echo "Seventh word in String is: ${Words[6]}" # (null) # Thank you, Francisco Lobo, for the suggestion. + It is, of course, possible to feed + the output of a here string + into the stdin of a loop. + +# As Seamus points out . . . + +ArrayVar=( element0 element1 element2 {A..D} ) + +while read element ; do + echo "$element" 1>&2 +done <<< $(echo ${ArrayVar[*]}) + +# element0 element1 element2 A B C D + Prepending a line to a file @@ -25905,6 +26039,8 @@ echo "Seventh word in String is: ${Words[6]}" # (null) line. command < input-file > output-file +# Or the equivalent: +< input-file command > output-file # Although this is non-standard. command1 | command2 | command3 > output-file See and . @@ -26128,7 +26264,7 @@ function doesOutput() nr=0 # We want the while loop to be able to manipulate these and -totalSize=0 #+ to be able to see the changes after the while finished. +totalSize=0 #+ to be able to see the changes after the 'while' finished. while read fileSize fileName ; do echo "$fileName is $fileSize bytes" @@ -26620,6 +26756,23 @@ echo "$var1" # 76 # From "insertion-sort.bash" example script. # Courtesy of JuanJo Ciarlante. + + +PORT=6881 # bittorrent + +# Scan the port to make sure nothing nefarious is going on. +netcat -l $PORT | tee>(md5sum ->mydata-orig.md5) | +gzip | tee>(md5sum - | sed 's/-$/mydata.lz2/'>mydata-gz.md5)>mydata.gz + +# Check the decompression: + gzip -d<mydata.gz | md5sum -c mydata-orig.md5) +# The MD5sum of the original checks stdin and detects compression issues. + +# Bill Davidsen contributed this example +#+ (with light edits by the ABS Guide author). + + + cat <(ls -l) # Same as ls -l | cat @@ -26761,7 +26914,8 @@ x=x < <(:) This second form will cheer the hearts of C programmers - (and is more portable). + (and is more portable). As in C, the function's opening bracket may optionally appear on the second line. @@ -26785,8 +26939,11 @@ x=x < <(:) In this case, however, a semicolon must follow the final command in the function. - fun () { echo "This is a function"; echo } # Error! -# ^ + fun () { echo "This is a function"; echo } # Error! +# ^ + +fun2 () { echo "Even a single-command function? Yes!"; } +# ^ Functions are called, triggered, simply by @@ -26847,6 +27004,17 @@ exit 0 # Will not exit here! # 2 +# Note that a function containing only comments is empty. + +func () +{ + # Comment 1. + # Comment 2. + # This is still an empty function. + # Thank you, Mark Bova, for pointing this out. +} +# Results in same error message as above. + # However ... @@ -26928,7 +27096,9 @@ foo # Thanks, S.C. and Christopher Head - Functions can take strange forms. + + Function names can take strange + forms. _(){ for i in {1..10}; do echo -n "$FUNCNAME"; done; echo; } # ^^^ No space between function name and parentheses. # This doesn't always work. Why not? @@ -26936,8 +27106,16 @@ foo # Now, let's invoke the function. _ # __________ # ^^^^^^^^^^ 10 underscores (10 x function name)! -# A "naked" underscore is an acceptable function name. - +# A "naked" underscore is an acceptable function name. + + +# In fact, a colon is likewise an acceptable function name. + +:(){ echo ":"; }; : + +# Of what use is this? +# It's a devious way to obfuscate the code in a script. + See also @@ -27308,7 +27486,54 @@ Function () # This doesn't work. linkend="codeblockref">block of code in which it appears. It has local scope. In a function, a local variable has - meaning only within that function block. + meaning only within that function block. + + + + However, as Thomas Braunberger points out, a local + variable declared in a function is also visible + to functions called by the parent + function. + + #!/bin/bash + +function1 () +{ + local func1var=20 + + echo "Within function1, \$func1var = $func1var." + + function2 +} + +function2 () +{ + echo "Within function2, \$func1var = $func1var." +} + +function1 + +exit 0 + + +# Output of the script: + +# Within function1, $func1var = 20. +# Within function2, $func1var = 20. + + This is documented in the Bash manual: + + Local can only be used within a function; + it makes the variable name have a visible scope + restricted to that function and its + children. [emphasis added] + The ABS Guide author considers this behavior + to be a bug. + + + + + Local variable visibility @@ -28402,6 +28627,7 @@ echo $? # 1 Generalizing the above into a script: #!/bin/bash +# This script must run with root permissions. URL="time.nist.gov/13" @@ -29005,7 +29231,18 @@ debecho $Whatever # (Will not echo.) Inserting set -u or set -o nounset in the script runs it, but gives an unbound variable error message - at each attempt to use an undeclared variable. + and aborts the script. + set -u # Or set -o nounset + +# Setting a variable to null will not trigger the error/abort. +# unset_var= + +echo $unset_var # Unset (and undeclared) variable. + +echo "Should not echo!" + +# sh t2.sh +# t2.sh: line 6: unset_var: unbound variable @@ -29093,6 +29330,11 @@ trap 'echo "Control-C disabled."' 2 &online; + + A Simple Implementation of a Progress Bar + &progressbar2; + + The argument to trap causes a specified action to execute @@ -29773,6 +30015,17 @@ fi an arithmetic value to a variable. + + The exit + status of an arithmetic expression is + not equivalent to an error + code. + var=1 && ((--var)) && echo $var +# ^^^^^^^^^ Here the and-list terminates with exit status 1. +# $var doesn't echo! +echo $? # 1 + + @@ -30779,15 +31032,17 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" There is, however, a major problem with all this. ANSI escape sequences are emphatically - non-portable. What works fine on some terminal - emulators (or the console) may work differently, or not - at all, on others. A colorized script that - looks stunning on the script author's machine may produce - unreadable output on someone else's. This somewhat compromises - the usefulness of colorizing scripts, and possibly relegates - this technique to the status of a gimmick. Colorized scripts - are probably inappropriate in a commercial setting, i.e., your - supervisor might disapprove. + non-portable. + What works fine on some terminal emulators (or the + console) may work differently, or not at all, on others. + A colorized script that looks stunning on the + script author's machine may produce unreadable output on + someone else's. This somewhat compromises the usefulness of + colorizing scripts, and possibly relegates this technique + to the status of a gimmick. Colorized scripts are probably + inappropriate in a commercial setting, i.e., your supervisor + might disapprove. Alister's ansi-color utility (based on Setting the path and umask at the beginning of a script makes - it more portable -- more likely to run on a - foreign machine whose user may have bollixed up the - $PATH and umask. + it more portable + -- more likely to run on a foreign machine + whose user may have bollixed up the $PATH + and umask. #!/bin/bash PATH=/bin:/usr/bin:/usr/local/bin ; export PATH umask 022 # Files that the script creates will have 755 permission. @@ -31798,9 +32054,10 @@ echo "User entered: "$answer"" Mortice Kern Associates add shell scripting capabilities to Windows. - There have been intimations that a future release of Windows - will contain Bash-like command-line scripting capabilities, - but that remains to be seen. + In 2006, Microsoft released the Windows Powershell, + which contains limited Bash-like command-line scripting + capabilities. @@ -32084,7 +32341,7 @@ echo $a # 6 /usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin/:/usr/games -bash$ PATH+=/opt/bin +bash$ PATH+=:/opt/bin bash$ echo $PATH /usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin/:/usr/games:/opt/bin @@ -32193,8 +32450,22 @@ echo $a # 6 A somewhat more elaborate address database &fetchaddress2; + + See for an interesting + usage of an associative array. + + Elements of the index array + may include embedded space + characters, or even leading and/or trailing space + characters. However, index array elements containing + only whitespace + are not permitted. + address[ ]="Blank" # Error! + + + Enhancements to the case construct: @@ -32886,7 +33157,7 @@ echo E-mails from certain spam-infested TLDs (61, 202, 211, 218, 220, etc.) will be trapped by spam filters and deleted unread. - However, if you have a problem getting a specific script + If you have a problem getting a particular script to work, you would be well advised to post to the comp.os.unix.shell Usenet newsgroup. @@ -32937,9 +33208,8 @@ echo - Update: upgraded to a A31 Thinkpad (P4-1.6, - 512 meg RAM) running FC8. No longer starving, and no longer - soliciting donations <g>. + Update: upgraded to a T60 Thinkpad + running Mandriva 2010. No longer starving <g>. @@ -33115,11 +33385,11 @@ echo Sebastian Arming, Chetankumar Phulpagare, Benno Schulenberg, Tedman Eng, Jochen DeSmet, Juan Nicolas Ruiz, Oliver Beckstein, Achmed Darwish, Dotan Barak, Richard Neill, Albert Siersema, - Omair Eshkenazi, Geoff Lee, JuanJo Ciarlante, Cliff Bamford, - Nathan Coulter, Ramses Rodriguez Martinez, Evgeniy Ivanov, - George Dimitriu, Kevin LeBlanc, Antonio Macchi, Tomas Pospisek, - Andreas Kühne, Pádraig Brady, and David Lawyer - (himself an author of four HOWTOs). + Omair Eshkenazi, Geoff Lee, Graham Ewart, JuanJo Ciarlante, + Cliff Bamford, Nathan Coulter, Ramses Rodriguez Martinez, + Evgeniy Ivanov, Craig Barnes, George Dimitriu, Kevin LeBlanc, + Antonio Macchi, Tomas Pospisek, Andreas Kühne, Pádraig + Brady, and David Lawyer (himself an author of four HOWTOs). My gratitude to Chet Ramey and Brian Fox for writing Bash, @@ -33132,7 +33402,7 @@ echo and lore, and has, to a great extent, enabled the publication of this book. - Thanks and appreciation to IBM, Red Hat, the Thanks and appreciation to IBM, Red Hat, Google, the Free Software Foundation, and all the good people fighting the good fight to keep Open Source software free and open. @@ -33156,17 +33426,17 @@ echo No liability for the contents of this document can be accepted. Use the concepts, examples and information at your own risk. There may be errors, omissions, and inaccuracies - that could cause you to lose data or harm your system, so - proceed with appropriate caution. The - author takes no responsibility for any damages, incidental or - otherwise. + that could cause you to lose data, harm your system, or induce + involuntary electrocution, so proceed with appropriate + caution. The author takes no responsibility for any + damages, incidental or otherwise. As it happens, it is highly unlikely that either you or - your system will suffer ill effects. In fact, the - raison d'etre of this book is to - enable its readers to analyze shell scripts and determine whether - they have unanticipated - consequences. + your system will suffer ill effects, aside from uncontrollable + hiccups. In fact, the raison + d'etre of this book is to enable its readers + to analyze shell scripts and determine whether they have unanticipated consequences. @@ -33704,10 +33974,9 @@ echo - Chet Ramey's Bash FAQ, - and mirror - site. + Chet Ramey's + Bash + FAQ. @@ -33718,16 +33987,6 @@ echo - - - Ed Schaefer's Shell - Corner - in Unix Review. - - - Example shell scripts at - - - Example shell scripts at joyent. - - - - Steve Parker's Shell Programming - Stuff. + Stuff. In fact, all of his shell scripting + books are highly recommended. See also Steve's Arcade + Games written in a shell script. @@ -33825,18 +34079,6 @@ echo gawk manuals. As you recall, gawk is the enhanced GNU version of awk. - - Another site for the GNU gawk - reference manual. - - - - - - - Eric Pement's - sed resources page. @@ -33900,9 +34142,18 @@ echo Rick - Hohensee has written the - osimpa i386 assembler entirely as Bash scripts. + Hohensee has written the + osimpa i386 assembler + entirely as Bash scripts. + + + + + + dgatwood + has a very nice + shell script games site, featuring a Tetris® + clone and solitaire. @@ -33928,12 +34179,11 @@ echo William Park - has been working on a project + has been working on a project to incorporate certain Awk and Python features into Bash. Among these is - a gdbm interface. He has released bashdiff + a gdbm interface. He has released + bashdiff on Freshmeat.net. He has an article @@ -33946,7 +34196,6 @@ echo url="http://linuxgazette.net/110/park.htm">yet another in the January, 2005 issue. - @@ -34476,11 +34725,21 @@ echo &showallc; + + Morse Code Practice + &samorse; + + Base64 encoding/decoding &base64; + + The Gronsfeld Cipher + &gronsfeld; + + To end this section, a review of the basics . . . and more. @@ -36679,9 +36938,10 @@ var=$(history); echo "$var" # $var is empty. - The Advancing in the - Bash Shell site gives a good introduction to the use of - history commands in Bash. + The Advancing + in the Bash Shell site gives a good introduction to + the use of history commands in Bash. @@ -37511,6 +37771,20 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUM + + ASCII + to Integer + + The atoi function in + C converts a string character to + an integer. Write a shell script function that performs + the same operation. Likewise, write a shell script function + that does the inverse, mirroring the C + itoa function which converts an + integer into an ASCII character. + + + Managing Disk Space @@ -38071,25 +38345,6 @@ done - - Morse Code - - Convert a text string (or optionally a text file) to - Morse code. Each character of the string will be represented - as a corresponding Morse code group of dots and dashes - (underscores), separated by whitespace from the next. For - example: - Invoke the "morse.sh" script with "script" -as an argument to convert to Morse. - - -$ sh morse.sh script - -... _._. ._. .. .__. _ -s c r i p t - - - Hex Dump @@ -38384,7 +38639,9 @@ fairly detailed description of the Playfair Cipher and its solution methods.The script will make extensive use of arrays and functions. + linkend="functionref">functions. + You may use as an + inspiration. @@ -38732,6 +38989,11 @@ thegrendel@theriver.com 30 Apr 2011 SWOZZLEBERRY release: Major update. + + + 30 Aug 2011 + VORTEXBERRY release: Minor update. + @@ -38754,6 +39016,9 @@ thegrendel@theriver.com A pdf version is also available. + There is likewise an + epub version, courtesy of Craig Barnes. The change @@ -38843,6 +39108,10 @@ A3. The modified or derivative document must be distributed under this same license, and the original author's copyright, as applicable, may not be modified. +A4. This License Appendix is invariant, may not be modified, and may not + be omitted from any otherwise modified variants or derivatives of + this document. + B. This document, or any modified or derivative version thereof, may NOT be distributed encrypted or with any form of DRM (Digital Rights @@ -38906,7 +39175,9 @@ distributors, or any of its associated software or documentation.The commercial print and other rights to this book are available. Please contact the author if - interested. + interested. As of this date, August 2011, limited print rights + (Lulu edition) have been granted to Steve Glines and to no + one else. The author produced this book in a manner consistent with the spirit of the LDP @@ -38941,11 +39212,19 @@ distributors, or any of its associated software or documentation.Russian, Czech, Chinese, - Indonesian, and Dutch translations are also available or in - progress. If you wish to translate this document into another + Indonesian, Dutch, and Romanian translations are also available or + in progress. If you wish to translate this document into another language, please feel free to do so, subject to the terms stated above. The author wishes to be notified of such efforts. + For those readers who absolutely insist on making + a donation to the author, you may contribute a small amount + via Paypal to my e-mail address, + thegrendel.abs@gmail.com. Note that this + is emphatically not necessary, or even + recommended. This book is a free and freely distributed document + for the use and enjoyment of the Linux community. + @@ -38953,8 +39232,9 @@ distributors, or any of its associated software or documentation.ASCII Table - In a book of this sort it is traditional to have an - ASCII Table appendix. This book does not. Instead, here is a short + By tradition, a book of this sort has an ASCII Table appendix. + This book does not. Instead, here is a short shell script that generates a complete ASCII table and writes it to the file ASCII.txt. diff --git a/LDP/guide/docbook/abs-guide/agram.sh b/LDP/guide/docbook/abs-guide/agram.sh index 38160c56..237dd4ea 100644 --- a/LDP/guide/docbook/abs-guide/agram.sh +++ b/LDP/guide/docbook/abs-guide/agram.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/agram2.sh b/LDP/guide/docbook/abs-guide/agram2.sh index 9b3ab2fb..d15c300c 100644 --- a/LDP/guide/docbook/abs-guide/agram2.sh +++ b/LDP/guide/docbook/abs-guide/agram2.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/base64.sh b/LDP/guide/docbook/abs-guide/base64.sh index 8721caca..e8cafc7b 100644 --- a/LDP/guide/docbook/abs-guide/base64.sh +++ b/LDP/guide/docbook/abs-guide/base64.sh @@ -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 <vladz@devzero.fr> # 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 diff --git a/LDP/guide/docbook/abs-guide/brownian.sh b/LDP/guide/docbook/abs-guide/brownian.sh index 155cdaa0..30a85cd4 100644 --- a/LDP/guide/docbook/abs-guide/brownian.sh +++ b/LDP/guide/docbook/abs-guide/brownian.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/cannon.sh b/LDP/guide/docbook/abs-guide/cannon.sh index 009a8113..0474383e 100644 --- a/LDP/guide/docbook/abs-guide/cannon.sh +++ b/LDP/guide/docbook/abs-guide/cannon.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/case-cmd.sh b/LDP/guide/docbook/abs-guide/case-cmd.sh index fba242bd..8243ba83 100644 --- a/LDP/guide/docbook/abs-guide/case-cmd.sh +++ b/LDP/guide/docbook/abs-guide/case-cmd.sh @@ -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";; diff --git a/LDP/guide/docbook/abs-guide/collatz.sh b/LDP/guide/docbook/abs-guide/collatz.sh index e21a67f6..1c4cab3f 100644 --- a/LDP/guide/docbook/abs-guide/collatz.sh +++ b/LDP/guide/docbook/abs-guide/collatz.sh @@ -11,7 +11,7 @@ # 6) NUMBER <-- 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++)) diff --git a/LDP/guide/docbook/abs-guide/continue-n.example b/LDP/guide/docbook/abs-guide/continue-n.example index f17168fc..75bdcde3 100644 --- a/LDP/guide/docbook/abs-guide/continue-n.example +++ b/LDP/guide/docbook/abs-guide/continue-n.example @@ -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: diff --git a/LDP/guide/docbook/abs-guide/cw-solver.sh b/LDP/guide/docbook/abs-guide/cw-solver.sh index f9a1e0da..5da6a770 100644 --- a/LDP/guide/docbook/abs-guide/cw-solver.sh +++ b/LDP/guide/docbook/abs-guide/cw-solver.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/dereference.sh b/LDP/guide/docbook/abs-guide/dereference.sh index b6123a95..17fe3662 100644 --- a/LDP/guide/docbook/abs-guide/dereference.sh +++ b/LDP/guide/docbook/abs-guide/dereference.sh @@ -5,7 +5,7 @@ dereference () { - y=\$"$1" # Name of variable. + y=\$"$1" # Name of variable (not value!). echo $y # $Junk x=`eval "expr \"$y\" "` diff --git a/LDP/guide/docbook/abs-guide/directory-info.sh b/LDP/guide/docbook/abs-guide/directory-info.sh index 2748fdba..1c874ebc 100644 --- a/LDP/guide/docbook/abs-guide/directory-info.sh +++ b/LDP/guide/docbook/abs-guide/directory-info.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/escaped.sh b/LDP/guide/docbook/abs-guide/escaped.sh index 0282d109..7f61cf15 100644 --- a/LDP/guide/docbook/abs-guide/escaped.sh +++ b/LDP/guide/docbook/abs-guide/escaped.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/ex14.sh b/LDP/guide/docbook/abs-guide/ex14.sh index dd0f3836..635a3a8e 100644 --- a/LDP/guide/docbook/abs-guide/ex14.sh +++ b/LDP/guide/docbook/abs-guide/ex14.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/ex49.sh b/LDP/guide/docbook/abs-guide/ex49.sh index f2c9bd95..e9f78974 100644 --- a/LDP/guide/docbook/abs-guide/ex49.sh +++ b/LDP/guide/docbook/abs-guide/ex49.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/exercising-dd.sh b/LDP/guide/docbook/abs-guide/exercising-dd.sh index 48a5bc45..81cb7626 100644 --- a/LDP/guide/docbook/abs-guide/exercising-dd.sh +++ b/LDP/guide/docbook/abs-guide/exercising-dd.sh @@ -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 $? diff --git a/LDP/guide/docbook/abs-guide/from.sh b/LDP/guide/docbook/abs-guide/from.sh index 6d86ebcf..5a7cee28 100644 --- a/LDP/guide/docbook/abs-guide/from.sh +++ b/LDP/guide/docbook/abs-guide/from.sh @@ -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 . . . diff --git a/LDP/guide/docbook/abs-guide/gronsfeld.bash b/LDP/guide/docbook/abs-guide/gronsfeld.bash new file mode 100644 index 00000000..91285f85 --- /dev/null +++ b/LDP/guide/docbook/abs-guide/gronsfeld.bash @@ -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è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. +# ************************************************************** # diff --git a/LDP/guide/docbook/abs-guide/is_spammer.bash b/LDP/guide/docbook/abs-guide/is_spammer.bash index e26a33bf..f6464b64 100644 --- a/LDP/guide/docbook/abs-guide/is_spammer.bash +++ b/LDP/guide/docbook/abs-guide/is_spammer.bash @@ -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 diff --git a/LDP/guide/docbook/abs-guide/life.sh b/LDP/guide/docbook/abs-guide/life.sh index 3f963a90..da08ef14 100644 --- a/LDP/guide/docbook/abs-guide/life.sh +++ b/LDP/guide/docbook/abs-guide/life.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/m4.sh b/LDP/guide/docbook/abs-guide/m4.sh index cd176941..75107ca5 100644 --- a/LDP/guide/docbook/abs-guide/m4.sh +++ b/LDP/guide/docbook/abs-guide/m4.sh @@ -8,7 +8,8 @@ echo "substr($string,4)" | m4 # A01 echo "regexp($string,[0-1][0-1],\&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 diff --git a/LDP/guide/docbook/abs-guide/makedict.sh b/LDP/guide/docbook/abs-guide/makedict.sh index 44b23201..ebf07947 100644 --- a/LDP/guide/docbook/abs-guide/makedict.sh +++ b/LDP/guide/docbook/abs-guide/makedict.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/maned.sh b/LDP/guide/docbook/abs-guide/maned.sh index 201b0a6d..0c2b9177 100644 --- a/LDP/guide/docbook/abs-guide/maned.sh +++ b/LDP/guide/docbook/abs-guide/maned.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/monthlypmt.sh b/LDP/guide/docbook/abs-guide/monthlypmt.sh index 8b40ce5b..08db7858 100644 --- a/LDP/guide/docbook/abs-guide/monthlypmt.sh +++ b/LDP/guide/docbook/abs-guide/monthlypmt.sh @@ -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," diff --git a/LDP/guide/docbook/abs-guide/multiplication.sh b/LDP/guide/docbook/abs-guide/multiplication.sh index 06590d69..2cdf371c 100644 --- a/LDP/guide/docbook/abs-guide/multiplication.sh +++ b/LDP/guide/docbook/abs-guide/multiplication.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/names.data b/LDP/guide/docbook/abs-guide/names.data index 30153574..21c6c950 100644 --- a/LDP/guide/docbook/abs-guide/names.data +++ b/LDP/guide/docbook/abs-guide/names.data @@ -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 diff --git a/LDP/guide/docbook/abs-guide/neg-array.sh b/LDP/guide/docbook/abs-guide/neg-array.sh index af225aa4..80a83452 100644 --- a/LDP/guide/docbook/abs-guide/neg-array.sh +++ b/LDP/guide/docbook/abs-guide/neg-array.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/neg-offset.sh b/LDP/guide/docbook/abs-guide/neg-offset.sh index ba2891cc..ba561a69 100644 --- a/LDP/guide/docbook/abs-guide/neg-offset.sh +++ b/LDP/guide/docbook/abs-guide/neg-offset.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/nightly-backup.sh b/LDP/guide/docbook/abs-guide/nightly-backup.sh index d5c1c366..c263699b 100644 --- a/LDP/guide/docbook/abs-guide/nightly-backup.sh +++ b/LDP/guide/docbook/abs-guide/nightly-backup.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/progress-bar2.sh b/LDP/guide/docbook/abs-guide/progress-bar2.sh new file mode 100644 index 00000000..6850d4ae --- /dev/null +++ b/LDP/guide/docbook/abs-guide/progress-bar2.sh @@ -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 $? diff --git a/LDP/guide/docbook/abs-guide/psub.bash b/LDP/guide/docbook/abs-guide/psub.bash index 91aad498..4f1102e9 100644 --- a/LDP/guide/docbook/abs-guide/psub.bash +++ b/LDP/guide/docbook/abs-guide/psub.bash @@ -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[@]}" diff --git a/LDP/guide/docbook/abs-guide/qky.sh b/LDP/guide/docbook/abs-guide/qky.sh index 73809535..52199bd7 100644 --- a/LDP/guide/docbook/abs-guide/qky.sh +++ b/LDP/guide/docbook/abs-guide/qky.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/sam.sh b/LDP/guide/docbook/abs-guide/sam.sh new file mode 100644 index 00000000..ef05c042 --- /dev/null +++ b/LDP/guide/docbook/abs-guide/sam.sh @@ -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. diff --git a/LDP/guide/docbook/abs-guide/test-suite.sh b/LDP/guide/docbook/abs-guide/test-suite.sh index ffc6e116..029de6b0 100644 --- a/LDP/guide/docbook/abs-guide/test-suite.sh +++ b/LDP/guide/docbook/abs-guide/test-suite.sh @@ -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 $? diff --git a/LDP/guide/docbook/abs-guide/userlist.sh b/LDP/guide/docbook/abs-guide/userlist.sh index ace1f425..ec80f495 100644 --- a/LDP/guide/docbook/abs-guide/userlist.sh +++ b/LDP/guide/docbook/abs-guide/userlist.sh @@ -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? diff --git a/LDP/guide/docbook/abs-guide/wh-loopc.sh b/LDP/guide/docbook/abs-guide/wh-loopc.sh index 5115f969..026a2ade 100644 --- a/LDP/guide/docbook/abs-guide/wh-loopc.sh +++ b/LDP/guide/docbook/abs-guide/wh-loopc.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/what.sh b/LDP/guide/docbook/abs-guide/what.sh index 043dcd61..aa5324e2 100644 --- a/LDP/guide/docbook/abs-guide/what.sh +++ b/LDP/guide/docbook/abs-guide/what.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/wipedir.sh b/LDP/guide/docbook/abs-guide/wipedir.sh index 90b8a28b..3d599a85 100644 --- a/LDP/guide/docbook/abs-guide/wipedir.sh +++ b/LDP/guide/docbook/abs-guide/wipedir.sh @@ -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 diff --git a/LDP/guide/docbook/abs-guide/wstrings.sh b/LDP/guide/docbook/abs-guide/wstrings.sh index 2a76559f..305163d7 100644 --- a/LDP/guide/docbook/abs-guide/wstrings.sh +++ b/LDP/guide/docbook/abs-guide/wstrings.sh @@ -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 $?