This commit is contained in:
gferg 2009-09-29 15:08:03 +00:00
parent 2692e2e626
commit 2295811a63
27 changed files with 1428 additions and 278 deletions

View File

@ -7,36 +7,146 @@
==================================================================
Current version = 6.0.05
Dated 03/24/09
Current version = 6.1
Dated 09/30/09
http://bash.neuralshortcircuit.com/abs-guide-latest.tar.bz2
http://bash.neuralshortcircuit.com/abs-guide.pdf
--------------------------------------------------------------------
News: Major update, version 6.0.
Coverage of version 4 of Bash.
News: Version 6.1 released!
====================================================================
Intermediate release
Working toward Version 6.1, Buffaloberry release
Version 6.1, Buffaloberry release
September 30, 2009
1) In "Internal Commands and Builtins" chapter
1) In "Shell Programming!" chapter,
Added new sidebar to the intro text.
2) In Quoting Variables section of "Quoting" chapter,
Revised double-quoting footnote about apparent inconsistent
behavior of "\" ...
(Thank you, Daniel Barclay for the heads-up!)
3) In "Special Characters" chapter:
Added $[ ... ] integer expansion entry.
At "&>" entry, added usage examples.
4) In "Tests" chapter:
In "Other Comparison Operators" section:
Expanded "compound comparison" section to include rihad's caution
about -a and -o operators not "short-circuiting."
At "[" entry, added footnote defining "token."
5) In "Internal Commands and Builtins" chapter,
At "eval" entry, reworded intro and added material to first example.
Subsequently rewrote first example once again, per suggestion by
Gerrit. (Thanks!)
Removed "eval.example" script, since it was misleading and confusing,
per the suggestion of Nathan Coulter.
Added footnote per Nathan Coulter to introductory paragraph. (Thanks!)
2) In "External Commands" chapter:
6) In "External Commands" chapter:
In "Math Commands" section:
At "dc" entry, added two short usage example, including a
somewhat cryptic one (Golden Ratio calculation).
At "dc" entry, added two short usage example, including a
somewhat cryptic one (Golden Ratio calculation).
Fixed typo (extra quoe at close) at inline "dc" example.
(Thank you, Daniel Scott Matthews!)
In "File and Archiving Commands" section:
Added entry for "openssl," with usage examples.
Added entry for "getfact" and "setfacl," with usage examples.
Added two footnotes to "sum, cksum, md5sum, sha1sum" entry.
In "External Commands" section:
In "ex33.sh" example, changed "NO_ARGS=86" to "NO_ARGS=0"
per alert from Gerrit. (Thanks!)
3) In "Internal Variables" section of "Variables Revisited" chapter:
At "$DIRSTACK" entry, added footnote defining "stack."
7) In "Variables Revisited" chapter:
In "Parameter Substitution" section,
Fixed typos at "${var%Pattern}, ${var%%Pattern}" entry.
(Thank you, Donald White, for pointing this out!)
At "${parameter-default}" entry, added snippet from
revised "hanoi2.bash" script to usage example.
In "Internal Variables" section,
At "$DIRSTACK" entry, added footnote defining "stack."
In "Indirect References" section,
Added a sidebar explaining the actual process of constructing
an indirect reference.
At "unset" entry, added note linking to ${parameter:-default}
parameter substitution construct.
(Thank you, Timothy Redaelli, for pointing out the ambiguity
here.)
In "Internal Variables" section,
Added $CDPATH entry.
4) In "Bash, versions 2, 3, and 4" chapter:
In "Bash, version 4" section,
Corrected a typo in Substring Extraction entry example script.
8) In "Command Substitution" chapter:
Enhanced "setting a variable to the contents of a file"
in-line example.
5) In "Bibliography" section:
Added entry for Wikipedia article on "dc."
9) In "Functions" chapter:
At "exit status" entry, added statement relating function exit status
to that of ordinary commands.
10) In "Bash, versions 2, 3, and 4" chapter:
In "Bash, version 4" section,
Corrected a typo in Substring Extraction entry example script.
Removed quoting of matched variable with =~ operator.
(Thank you, Thomas Güttler, for pointing this out.)
11) In the "Miscellany" chapter:
In the "Portability Issues" section,
Added Larry Wall epigraph.
In the "Interactive and non-interactive shells and scripts" section,
Added John Lange's examples using "if [ -t 0 ]" ...
Added a new sub-subsection with a "test-suite.sh" script.
12) In "Process Substitution" chapter:
Added instances to first usage example.
Stylistic cleanups.
13) In "Exit and Exit Status" chapter,
Added discussion of exit status of a _pipe_,
including effect of prefixing the pipe with ! ...
14) In "Arrays Chapter,
Fixed comment in "ex68.sh" example -- 1 is not a prime.
Thank you, Gordon Hopper, for pointing this out.
Fixed error in comment "ex67.sh" example.
(Thank you Grigory Romanenkov, for pointing this out.)
15) In "Here Documents" chapter:
Added cautionary note about the use of ! as a limit string.
At quoting/escaping the limit string discussion, added Allen
Halsey's explanation. (Thank you!)
16) In "Bash, versions 2, 3, and 4" chapter:
At "coproc" entry, fixed examples and added commentary,
courtesy of George Dimitriu. (Thanks!)
17) In "Endnotes" chapter:
In "Where to Go For Help" section,
Added "CI-300 printer manual" epigraph.
18) In "Bibliography" section:
Added entry for Wikipedia article on "dc."
Added entry for Philip Patterson's "logforbash" script.
19) Changed several instances of "print $9" to "print $8" in embedded
awk scripts. (Thank you, Michal Nagy, for the heads up.)
20) Added a new appendix: "An Introduction to Programmable Completion."
Added the following support scripts:
"UseGetOpt-2.sh" and "UseGetOpt-2"
21) In "Contributed Scripts" appendix:
Fixed up "hanoi2.bash" script so it doesn't crash with error
if no params.
(Thank you, Stephen Solomon, for the heads up!)
Added "show-all-colors.sh" example script,
courtesy of Chetankumar Phulpagare.
22) Updated download URL.
23) Cleanups/fixups to main text, appendices, and script examples where
appropriate.

View File

@ -278,7 +278,7 @@
<para><command>! </command>
<link linkend="notref">Negation operator</link>, inverts <link
linkend="exitstatusref">exit status</link> of a test or command
linkend="negcond">exit status</link> of a test or command
<itemizedlist>
<listitem><para><command>!= </command>
<link linkend="notequal">not-equal-to</link>
@ -357,7 +357,14 @@
<para><command>" ... " </command>
(double quotes)
<link linkend="dblquo"><firstterm>weak</firstterm>
quoting</link></para>
quoting</link>
<itemizedlist>
<listitem><para><link
linkend="quotingbsl"><firstterm>Double-quoting</firstterm>
the <firstterm>backslash</firstterm> (<command>\</command>)
character</link></para></listitem>
</itemizedlist>
</para>
<para><command>,</command>
<itemizedlist>
@ -417,7 +424,6 @@
</listitem>
</itemizedlist></para>
<para><command>[[ ... ]]</command>
<link linkend="dblbrackets">Double brackets</link>,
extended <firstterm>test</firstterm> construct</para>
@ -436,6 +442,11 @@
using <link linkend="backticksref">backquotes</link>
notation</para>
<para><command>$[ ... ]</command>
<link linkend="bracketarith">Integer expansion</link>
(deprecated)</para>
<!-- ********************** -->
<para><command>${ ... }</command> Variable manipulation / evaluation
@ -1053,6 +1064,7 @@
</itemizedlist>
</para>
<para><link linkend="checksumref">Checksum</link></para>
<para><link linkend="childref">Child processes</link></para>
<para><link linkend="nullref">Colon</link>, <command>: </command>,
equivalent to the <link linkend="trueref">true</link> Bash
@ -1060,6 +1072,8 @@
<para><link linkend="colorizingref">Colorizing scripts</link>
<itemizedlist>
<listitem><para>Cycling through the background colors, <link
linkend="showallc">example script</link></para></listitem>
<listitem><para><link
linkend="coloriztable"><command>Table</command></link> of
color escape sequences</para></listitem>
@ -1095,7 +1109,8 @@
</para></listitem>
<listitem><para><link linkend="csvl">Setting variable from loop output</link>
</para></listitem>
<listitem><para><link linkend="csws">Word splitting</link></para></listitem>
<listitem><para><link linkend="csws">Word
splitting</link></para></listitem>
</itemizedlist></para>
<para><link linkend="commenth">Comment headers</link>,
@ -1278,8 +1293,17 @@
<para><link linkend="dblparensref">Double parentheses</link>
<command>(( ... )) </command> arithmetic expansion/evaluation
construct</para>
<para><link linkend="dblquo">Double quotes</link>
<command>" ... "</command> <firstterm>weak</firstterm> quoting</para>
<command>" ... "</command> <firstterm>weak</firstterm> quoting
<itemizedlist>
<listitem><para><link
linkend="quotingbsl"><firstterm>Double-quoting</firstterm>
the <firstterm>backslash</firstterm> (<command>\</command>)
character</link></para></listitem>
</itemizedlist>
</para>
<para><link linkend="doublespace">Double-spacing a text
file</link>, using <link linkend="sedref">sed</link></para>
@ -1304,6 +1328,8 @@
Contraction of <firstterm>else</firstterm>
and <link linkend="ifthen">if</link></para>
<para><link linkend="elseref">else</link></para>
<para>Encrypting files, using <link
linkend="opensslref">openssl</link></para>
<para><link linkend="caseesac1">esac</link>, keyword terminating
<firstterm>case</firstterm> construct</para>
<para><link linkend="envref"><firstterm>Environmental</firstterm>
@ -1365,6 +1391,8 @@
<firstterm>Exit
codes</firstterm> with special meanings</para>
<para><link linkend="excoor">Out of range</link></para>
<para><link linkend="pipeex"><firstterm>Pipe</firstterm></link>
exit status</para>
<para><link linkend="exitreturn1">
Specified by a <firstterm>function
return</firstterm></link></para>
@ -1461,6 +1489,9 @@
</itemizedlist>
<para><link linkend="opensslref">File encryption</link></para>
<para><link linkend="findref">find</link>
<itemizedlist>
<listitem><para><command>{} </command>
@ -1683,6 +1714,8 @@
<listitem><para><link
linkend="limitstringref"><firstterm>Limit</firstterm>
string</link></para>
<para><link linkend="exclls"><token>!</token> as a
<firstterm>limit string</firstterm></link></para>
<para><link linkend="indentedls">Closing <firstterm>limit
string</firstterm></link> may not be indented</para>
<para><link linkend="limitstrdash">Dash option</link>
@ -2035,6 +2068,8 @@
<para><link linkend="oldpwd"><varname>$OLDPWD</varname></link>
Previous working directory</para>
<para><link linkend="opensslref">openssl</link> encryption
utility</para>
<para>Operator
<itemizedlist>
<listitem><para><link linkend="operatordef">Definition
@ -2042,7 +2077,6 @@
<listitem><para><link
linkend="opprecedence1">Precedence</link></para></listitem>
</itemizedlist></para>
<para><link linkend="optionsref">Options</link>,
passed to shell or script on command line or by <link
linkend="setref">set</link> command</para>
@ -2129,8 +2163,6 @@
same file with a <firstterm>Bash</firstterm> script</para></listitem>
<listitem><para><link linkend="perlemb">Embedded</link> in a
<firstterm>Bash</firstterm> script</para></listitem>
<listitem><para><link linkend="evalx0">Using <firstterm>eval</firstterm>
with</link></para></listitem>
</itemizedlist></para>
<para><link linkend="qky"><emphasis>Perquackey</emphasis>-type
@ -2155,6 +2187,8 @@
<listitem><para><link
linkend="comminpipe"><firstterm>Comments</firstterm> embedded
within</link></para></listitem>
<listitem><para><link linkend="pipeex">Exit status</link>
of a pipe</para></listitem>
<listitem><para><link linkend="pipefailref">Pipefail</link>,
<firstterm>set -o pipefail</firstterm>
option to indicate <link linkend="exitstatusref">exit status</link>
@ -2194,6 +2228,10 @@
<link linkend="indentedls">indenting</link></para></listitem>
<listitem><para><link linkend="dosnewlines">DOS-type newlines
(<token>\r\n</token>)</link> crash a script</para></listitem>
<listitem><para><link
linkend="quotingbsl"><firstterm>Double-quoting</firstterm>
the <firstterm>backslash</firstterm> (<command>\</command>)
character</link></para></listitem>
<listitem><para><link linkend="evalrisk">eval</link>, risk of
using</para></listitem>
<listitem><para><link linkend="execperm">Execute permission
@ -2285,6 +2323,10 @@
<listitem><para><link
linkend="setpum">Setting <firstterm>path</firstterm>
and <firstterm>umask</firstterm></link></para></listitem>
<listitem><para><link
linkend="testsuite0">A <firstterm>test suite</firstterm>
script</link> (Bash versus classic Bourne
shell)</para></listitem>
<listitem><para><link
linkend="whatisref3">Using <firstterm>whatis</firstterm></link>
</para></listitem>
@ -2382,6 +2424,8 @@
<firstterm>subshell</firstterm></link></para></listitem>
</itemizedlist></para>
<!-- *************************************************************** -->
<para><link linkend="tabexpansion">Programmable completion</link>
(tab expansion)</para>
<para>Prompt
<itemizedlist>
@ -2951,6 +2995,7 @@
<para>* * *</para>
<para><link linkend="tabexpansion">Tab completion</link></para>
<para>Table lookup, <link linkend="resistor">script
example</link></para>
<para><link linkend="tailref">tail</link>, <firstterm>echo</firstterm>
@ -3155,6 +3200,9 @@
<listitem><para><link
linkend="pseudocoderef">Pseudo-code</link></para></listitem>
<listitem><para><link linkend="rcsref">rcs</link></para></listitem>
<listitem><para><link
linkend="devnullredirect">Redirecting a <firstterm>test</firstterm>
to <filename>/dev/null</filename</link> to suppress output</para></listitem>
<listitem><para><link linkend="runpartsref2">Running scripts in
sequence</link> without user intervention, using <link
linkend="runpartsref">run-parts</link></para></listitem>
@ -3179,6 +3227,9 @@
</para></listitem>
<listitem><para><link linkend="intparam">Testing a variable</link>
to see if it contains only digits</para></listitem>
<listitem><para><link linkend="devnullredirect">Testing whether
a command exists</link>, using <link
linkend="typeref">type</link></para></listitem>
<listitem><para><link
linkend="trackingscr">Tracking script
usage</link></para></listitem>
@ -3195,6 +3246,9 @@
<para><link linkend="tmoutref"><varname>$TMOUT</varname></link>,
Timeout interval</para>
<para><link linkend="tokenref">Token</link>, a symbol that may
expand to a <link linkend="keywordref">keyword</link> or
command</para>
<para><link linkend="tputref">tput</link>, terminal-control
command</para>
@ -3436,6 +3490,16 @@
<listitem><para><link linkend="wdotfilewc">Will not match
<filename>dot files</filename></link></para></listitem>
</itemizedlist></para>
<para>Word splitting
<itemizedlist>
<listitem><para><link
linkend="wsplitref">Definition</link></para></listitem>
<listitem><para><link
linkend="csws">Resulting from <firstterm>command
substitution</firstterm></link></para></listitem>
</itemizedlist></para>
<para><link linkend="shwrapper">Wrapper</link>, shell</para>
<para>* * *</para>

View File

@ -119,3 +119,6 @@ paragraph-spac3.sh
sw.sh
line 5 (comment)
UseGetOpt.sh: line 4 (comment)
UseGetOpt-2.sh: line 11 (comment)

View File

@ -0,0 +1,165 @@
<title>An Introduction to Programmable Completion</title>
<para>The <firstterm>programmable completion</firstterm> feature in
Bash permits typing a partial command, then pressing the
<keycap>[Tab]</keycap> key to auto-complete the command sequence.
<footnote><para>This works only from the <firstterm>command
line</firstterm>, of course, and not within a
script.</para></footnote>
If multiple completions are possible, then <keycap>[Tab]</keycap>
lists them all. Let's see how it works.</para>
<para>
<screen>
<prompt>bash$ </prompt><userinput>xtra[Tab]</userinput>
<computeroutput>xtraceroute xtrapin xtrapproto
xtraceroute.real xtrapinfo xtrapreset
xtrapchar xtrapout xtrapstats</computeroutput>
<prompt>bash$ </prompt><userinput>xtrac[Tab]</userinput>
<computeroutput>xtraceroute xtraceroute.real</computeroutput>
<prompt>bash$ </prompt><userinput>xtraceroute.r[Tab]</userinput>
<computeroutput>xtraceroute.real</computeroutput>
</screen>
</para>
<para>Tab completion also works for variables and path names.</para>
<para>
<screen>
<prompt>bash$ </prompt><userinput>echo $BASH[Tab]</userinput>
<computeroutput>$BASH $BASH_COMPLETION $BASH_SUBSHELL
$BASH_ARGC $BASH_COMPLETION_DIR $BASH_VERSINFO
$BASH_ARGV $BASH_LINENO $BASH_VERSION
$BASH_COMMAND $BASH_SOURCE</computeroutput>
<prompt>bash$ </prompt><userinput>echo /usr/local/[Tab]</userinput>
<computeroutput>bin/ etc/ include/ libexec/ sbin/ src/
doc/ games/ lib/ man/ share/</computeroutput>
</screen>
</para>
<para><anchor id="completeref"></para>
<para>The Bash <command>complete</command> and
<command>compgen</command> <link
linkend="builtinref">builtins</link> make it
possible for <firstterm>tab completion</firstterm> to
recognize partial <firstterm>parameters</firstterm> and
<firstterm>options</firstterm> to commands. In a very simple case,
we can use <command>complete</command> from the command-line to
specify a short list of acceptable parameters.</para>
<screen>
<prompt>bash$ </prompt><userinput>touch sample_command</userinput>
<prompt>bash$ </prompt><userinput>touch file1.txt file2.txt file2.doc file30.txt file4.zzz</userinput>
<prompt>bash$ </prompt><userinput>chmod +x sample_command</userinput>
<prompt>bash$ </prompt><userinput>complete -f -X '!*.txt' sample_command</userinput>
<prompt>bash$ </prompt><userinput>./sample[Tab][Tab]</userinput>
<computeroutput>sample_command</computeroutput>
<computeroutput>file1.txt file2.txt file30.txt</computeroutput>
</screen>
<para>The <option>-f</option> option to
<firstterm>complete</firstterm> specifies filenames,
and <option>-X</option> the filter pattern.</para>
<para><anchor id="compgenref"></para>
<para>For anything more complex, we could write a script that
specifies a list of acceptable command-line parameters.
The <command>compgen</command> builtin expands a list of
<firstterm>arguments</firstterm> to <firstterm>generate</firstterm>
completion matches. </para>
<para>Let us take a <link linkend="usegetopt2">modified version</link>
of the <emphasis>UseGetOpt.sh</emphasis> script as an example
command. This script accepts a number of command-line parameters,
preceded by either a single or double dash. And here is the
corresponding <firstterm>completion script</firstterm>, by
convention given a filename corresponding to its associated
command.</para>
<example id="usegetoptex">
<title>Completion script for
<firstterm>UseGetOpt.sh</firstterm></title>
<programlisting>&usegetoptex;</programlisting>
</example>
<para>Now, let's try it.</para>
<screen>
<prompt>bash$ </prompt><userinput>source UseGetOpt-2</userinput>
<prompt>bash$ </prompt><userinput>./UseGetOpt-2.sh -[Tab]</userinput>
<computeroutput>-- --aoption --debug --file --help --log --test
-a -d -f -h -l -t</computeroutput>
<prompt>bash$ </prompt><userinput>./UseGetOpt-2.sh --[Tab]</userinput>
<computeroutput>-- --aoption --debug --file --help --log --test</computeroutput>
</screen>
<para>
We begin by <link linkend="sourceref">sourcing</link> the <quote>completion
script.</quote> This sets the command-line parameters.
<footnote><para>Normally the default parameter completion files reside
in either the <filename class="directory">/etc/profile.d</filename>
directory or in <filename
class="directory">/etc/bash_completion</filename>. These autoload on
system startup. So, after writing a useful completion script, you
might wish to move it (as <firstterm>root</firstterm>, of course)
to one of these directories.</para></footnote>
</para>
<para>In the first instance, hitting <keycap>[Tab]</keycap> after
a single dash, the output is all the possible parameters preceded by
<emphasis>one or more</emphasis> dashes. Hitting <keycap>[Tab]</keycap>
after <emphasis>two</emphasis> dashes gives the possible parameters
preceded by <emphasis>two or more</emphasis> dashes.</para>
<para>Now, just what is the point of having to jump through flaming
hoops to enable command-line tab completion? <emphasis>It saves
keystrokes.</emphasis>
<footnote><para>It has been extensively documented that
programmers are willing to put in long hours of effort in
order to save ten minutes of <quote>unnecessary</quote>
labor. This is known as
<firstterm>optimization</firstterm>.</para></footnote>
</para>
<para>--</para>
<para><emphasis>Resources:</emphasis></para>
<para>Bash <ulink url="http://freshmeat.net/projects/bashcompletion">
programmable completion</ulink> project</para>
<para>Mitch Frazier's <ulink
url="http://www.linuxjournal.com"><citetitle
pubwork="journal">Linux Journal</citetitle></ulink> article, <ulink
url="http://www.linuxjournal.com/content/more-using-bash-complete-command"><emphasis>More
on Using the Bash Complete Command</emphasis></ulink></para>
<para>Steve's excellent two-part article, <quote>An Introduction to Bash
Completion</quote>:
<ulink
url="http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_1">Part
1</ulink> and
<ulink url="http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_2">Part 2</ulink></para>

View File

@ -0,0 +1,27 @@
# file: UseGetOpt-2
# UseGetOpt-2.sh parameter-completion
_UseGetOpt-2 () # By convention, the function name
{ #+ starts with an underscore.
local cur
# Pointer to current completion word.
# By convention, it's named "cur" but this isn't strictly necessary.
COMPREPLY=() # Array variable storing the possible completions.
cur=${COMP_WORDS[COMP_CWORD]}
case "$cur" in
-*)
COMPREPLY=( $( compgen -W '-a -d -f -l -t -h --aoption --debug \
--file --log --test --help --' -- $cur ) );;
# Generate the completion matches and load them into $COMPREPLY array.
# xx) May add more cases here.
# yy)
# zz)
esac
return 0
}
complete -F _UseGetOpt-2 -o filenames ./UseGetOpt-2.sh
# ^^ ^^^^^^^^^^^^ Invokes the function _UseGetOpt-2.

View File

@ -0,0 +1,94 @@
#!/bin/bash
# UseGetOpt-2.sh
# Modified version of the script for illustrating tab-expansion
#+ of command-line options.
# See the "Introduction to Tab Expansion" appendix.
# Possible options: -a -d -f -l -t -h
#+ --aoption, --debug --file --log --test -- help --
# Author of original script: Peggy Russell &lt;prusselltechgroup@gmail.com&gt;
# UseGetOpt () {
declare inputOptions
declare -r E_OPTERR=85
declare -r ScriptName=${0##*/}
declare -r ShortOpts="adf:hlt"
declare -r LongOpts="aoption,debug,file:,help,log,test"
DoSomething () {
echo "The function name is '${FUNCNAME}'"
}
inputOptions=$(getopt -o "${ShortOpts}" --long \
"${LongOpts}" --name "${ScriptName}" -- "${@}")
if [[ ($? -ne 0) || ($# -eq 0) ]]; then
echo "Usage: ${ScriptName} [-dhlt] {OPTION...}"
exit $E_OPTERR
fi
eval set -- "${inputOptions}"
while true; do
case "${1}" in
--aoption | -a) # Argument found.
echo "Option [$1]"
;;
--debug | -d) # Enable informational messages.
echo "Option [$1] Debugging enabled"
;;
--file | -f) # Check for optional argument.
case "$2" in #+ Double colon is optional argument.
"") # Not there.
echo "Option [$1] Use default"
shift
;;
*) # Got it
echo "Option [$1] Using input [$2]"
shift
;;
esac
DoSomething
;;
--log | -l) # Enable Logging.
echo "Option [$1] Logging enabled"
;;
--test | -t) # Enable testing.
echo "Option [$1] Testing enabled"
;;
--help | -h)
echo "Option [$1] Display help"
break
;;
--) # Done! $# is argument number for "--", $@ is "--"
echo "Option [$1] Dash Dash"
break
;;
*)
echo "Major internal error!"
exit 8
;;
esac
echo "Number of arguments: [$#]"
shift
done
shift
# }
exit

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ column_number=$2 # Which column to total up.
# Begin awk script.
# ------------------------------------------------
# -------------------------------------------------
awk "
{ total += \$${column_number} # Indirect reference
@ -38,7 +38,8 @@ END {
}
" "$filename"
# ------------------------------------------------
# Note that awk doesn't need an eval preceding \$$.
# -------------------------------------------------
# End awk script.
# Indirect variable reference avoids the hassles

View File

@ -6,7 +6,7 @@
#+ since the decrypted password is sent in the clear.
# Use something like "ssh" if this is a concern.
E_BADARGS=65
E_BADARGS=85
if [ -z "$1" ]
then

View File

@ -1,34 +1,36 @@
#!/bin/bash
# Exercising getopts and OPTIND
# Script modified 10/09/03 at the suggestion of Bill Gradwohl.
# ex33.sh: Exercising getopts and OPTIND
# Script modified 10/09/03 at the suggestion of Bill Gradwohl.
# Here we observe how 'getopts' processes command-line arguments to script.
# The arguments are parsed as "options" (flags) and associated arguments.
# Try invoking this script with
# 'scriptname -mn'
# 'scriptname -oq qOption' (qOption can be some arbitrary string.)
# 'scriptname -qXXX -r'
# Try invoking this script with:
# 'scriptname -mn'
# 'scriptname -oq qOption' (qOption can be some arbitrary string.)
# 'scriptname -qXXX -r'
#
# 'scriptname -qr' - Unexpected result, takes "r" as the argument to option "q"
# 'scriptname -q -r' - Unexpected result, same as above
# 'scriptname -mnop -mnop' - Unexpected result
# (OPTIND is unreliable at stating where an option came from).
# 'scriptname -qr'
#+ - Unexpected result, takes "r" as the argument to option "q"
# 'scriptname -q -r'
#+ - Unexpected result, same as above
# 'scriptname -mnop -mnop' - Unexpected result
# (OPTIND is unreliable at stating where an option came from.)
#
# If an option expects an argument ("flag:"), then it will grab
#+ whatever is next on the command-line.
NO_ARGS=0
E_OPTERROR=65
E_OPTERROR=85
if [ $# -eq "$NO_ARGS" ] # Script invoked with no command-line args?
if [ $# -eq "$NO_ARGS" ] # Script invoked with no command-line args?
then
echo "Usage: `basename $0` options (-mnopqrs)"
exit $E_OPTERROR # Exit and explain usage, if no argument(s) given.
exit $E_OPTERROR # Exit and explain usage.
# Usage: scriptname -options
# Note: dash (-) necessary
fi
# Usage: scriptname -options
# Note: dash (-) necessary
while getopts ":mnopq:rs" Option
@ -38,22 +40,23 @@ do
n | o ) echo "Scenario #2: option -$Option- [OPTIND=${OPTIND}]";;
p ) echo "Scenario #3: option -p- [OPTIND=${OPTIND}]";;
q ) echo "Scenario #4: option -q-\
with argument \"$OPTARG\" [OPTIND=${OPTIND}]";;
with argument \"$OPTARG\" [OPTIND=${OPTIND}]";;
# Note that option 'q' must have an associated argument,
#+ otherwise it falls through to the default.
r | s ) echo "Scenario #5: option -$Option-";;
* ) echo "Unimplemented option chosen.";; # DEFAULT
* ) echo "Unimplemented option chosen.";; # Default.
esac
done
shift $(($OPTIND - 1))
# Decrements the argument pointer so it points to next argument.
# $1 now references the first non option item supplied on the command-line
# $1 now references the first non-option item supplied on the command-line
#+ if one exists.
exit 0
exit $?
# As Bill Gradwohl states,
# "The getopts mechanism allows one to specify: scriptname -mnop -mnop
#+ but there is no reliable way to differentiate what came from where
#+ by using OPTIND."
#+ but there is no reliable way to differentiate what came
#+ from where by using OPTIND."
# There are, however, workarounds.

View File

@ -18,6 +18,15 @@ echo
echo "==========================================================="
echo
eval "`seq 3 | sed -e 's/.*/echo var&=ABCDEFGHIJ/'`"
# var1=ABCDEFGHIJ
# var2=ABCDEFGHIJ
# var3=ABCDEFGHIJ
echo
echo "==========================================================="
echo
# Now, showing how to do something useful with "eval" . . .
# (Thank you, E. Choroba!)

View File

@ -10,8 +10,8 @@
MAX_ARG=5
E_WRONG_ARGS=65
E_RANGE_ERR=66
E_WRONG_ARGS=85
E_RANGE_ERR=86
if [ -z "$1" ]
@ -22,7 +22,7 @@ fi
if [ "$1" -gt $MAX_ARG ]
then
echo "Out of range (5 is maximum)."
echo "Out of range ($MAX_ARG is maximum)."
# Let's get real now.
# If you want greater range than this,
#+ rewrite it in a Real Programming Language.

View File

@ -30,8 +30,7 @@ do # List all the elements in the array.
# ${colors[index]} also works because it's within ${ ... } brackets.
let "index = $index + 1"
# Or:
# index+=1
# if running Bash, version 3.1 or later.
# ((index++))
done
# Each array element listed on a separate line.
# If this is not desired, use echo -n "${colors[$index]} "

View File

@ -62,7 +62,7 @@ sift () # Sift out the non-primes.
{
let i=$LOWER_LIMIT+1
# We know 1 is prime, so let's start with 2.
# Let's start with 2.
until [ "$i" -gt "$UPPER_LIMIT" ]
do

View File

@ -17,4 +17,25 @@ Endofmessage
# cat &lt;&lt;"Endofmessage"
# cat &lt;&lt;\Endofmessage
# And, likewise:
cat &lt;&lt;"SpecialCharTest"
Directory listing would follow
if limit string were not quoted.
`ls -l`
Arithmetic expansion would take place
if limit string were not quoted.
$((5 + 3))
A a single backslash would echo
if limit string were not quoted.
\\
SpecialCharTest
exit

View File

@ -20,7 +20,7 @@ do
continue # On to next.
fi
ls -l $file | awk '{ print $9 " file size: " $5 }' # Print 2 fields.
ls -l $file | awk '{ print $8 " file size: " $5 }' # Print 2 fields.
whatis `basename $file` # File info.
# Note that the whatis database needs to have been set up for this to work.
# To do this, as root run /usr/bin/makewhatis.

View File

@ -5,38 +5,41 @@
# http://hanoi.kernelthread.com
# hanoi2.bash
# Version 2: modded for ASCII-graphic display.
# Version 2.00: modded for ASCII-graphic display.
# Version 2.01: fixed no command-line param bug.
# Uses code contributed by Antonio Macchi,
#+ with heavy editing by ABS Guide author.
# This variant also falls under the original copyright, see above.
# This variant falls under the original copyright, see above.
# Used in ABS Guide with Amit Singh's permission (thanks!).
# Variables #
### Variables && sanity check ###
E_NOPARAM=86
E_BADPARAM=87 # Illegal no. of disks passed to script.
E_BADPARAM=87 # Illegal no. of disks passed to script.
E_NOEXIT=88
DISKS=$1
DISKS=${1:-E_NOPARAM} # Must specify how many disks.
Moves=0
MWIDTH=7
MARGIN=2
# Arbitrary "magic" constants, work okay for relatively small # of disks.
# Arbitrary "magic" constants; work okay for relatively small # of disks.
# BASEWIDTH=51 # Original code.
let "basewidth = $MWIDTH * $DISKS + $MARGIN" # "Base" beneath rods.
let "basewidth = $MWIDTH * $DISKS + $MARGIN" # "Base" beneath rods.
# Above "algorithm" could likely stand improvement.
# Display variables.
### Display variables ###
let "disks1 = $DISKS - 1"
let "spaces1 = $DISKS"
let "spaces2 = 2 * $DISKS"
let "lastmove_t = $DISKS - 1" # Final move?
let "lastmove_t = $DISKS - 1" # Final move?
declare -a Rod1 Rod2 Rod3
#################
### ######################### ###
function repeat { # $1=char $2=number of repetitions
@ -131,6 +134,7 @@ then # Last move? If yes, then display final position.
fi
}
# From here down, almost the same as original (hanoi.bash) script.
dohanoi() { # Recursive function.
@ -152,6 +156,7 @@ dohanoi() { # Recursive function.
esac
}
setup_arrays ()
{
local dim n elem
@ -179,7 +184,7 @@ case $# in
1)
disks=$1
dohanoi $1 1 3 2
# Total moves = 2^n - 1, where n = # of disks.
# Total moves = 2^n - 1, where n = number of disks.
echo
exit 0;
;;
@ -190,6 +195,7 @@ case $# in
esac
;;
*)
clear
echo "usage: $0 N"
echo " Where \"N\" is the number of disks."
exit $E_NOPARAM;

View File

@ -11,7 +11,8 @@ echo "\$var = $var" # $var = 23
echo "\$\$var = $$var" # $$var = 4570var
# Not useful ...
# \$\$ expanded to PID of process being executed,
# \$\$ expanded to PID of the script
# -- refer to the entry on the $$ variable --
#+ and "var" is echoed as plain text.
# (Thank you, Jakob Bohm, for pointing this out.)
@ -71,7 +72,8 @@ echo
# (Thanks, Stephane Chazelas, for clearing up the above behavior.)
# Another method is the ${!t} notation, discussed in "Bash, version 2" section.
# See also ex78.sh.
# A more straightforward method is the ${!t} notation, discussed in the
#+ "Bash, version 2" section.
# See also ex78.sh.
exit 0

View File

@ -4,7 +4,7 @@
# author: mendel cooper
# reldate: 12 Jan 2009
# license: public domain
# (Not much sense in GPLing something that's pretty much in the common
# (Not much sense GPLing something that's pretty much in the common
#+ domain anyhow.)
###################################################################
@ -17,7 +17,7 @@
# Could it be that he has a habit of partying into the wee hours #
#+ of the morning? #
# Possibly he leaves pizza crusts in the bed, empty beer bottles #
#+ all over the floor, and clogs the plumbing. ... #
#+ all over the floor, and clogs the plumbing. . . . #
# #
# ------------------------------------------------------------- #
# #

View File

@ -9,7 +9,10 @@ do
echo "{$line}"
last=$line
done
printf "\nAll done, last:$last\n"
echo
echo "++++++++++++++++++++++"
printf "\nAll done, last: $last\n"
exit 0 # End of code.
# (Partial) output of script follows.
@ -27,9 +30,10 @@ exit 0 # End of code.
{echo "{$line}"}
{last=$line}
{done}
{printf "nAll done, last:$lastn"}
{printf "nAll done, last: $lastn"}
All done, last:(null)
All done, last: (null)
The variable (last) is set within the subshell but unset outside.
The variable (last) is set within the loop/subshell
but its value does not persist outside the loop.

View File

@ -0,0 +1,51 @@
#!/bin/bash
# show-all-colors.sh
# Displays all 256 possible background colors, using ANSI escape sequences.
# Author: Chetankumar Phulpagare
# Used in ABS Guide with permission.
T1=8
T2=6
T3=36
offset=0
for num1 in {0..7}
do {
for num2 in {0,1}
do {
shownum=`echo "$offset + $T1 * ${num2} + $num1" | bc`
echo -en "\E[0;48;5;${shownum}m color ${shownum} \E[0m"
}
done
echo
}
done
offset=16
for num1 in {0..5}
do {
for num2 in {0..5}
do {
for num3 in {0..5}
do {
shownum=`echo "$offset + $T2 * ${num3} \
+ $num2 + $T3 * ${num1}" | bc`
echo -en "\E[0;48;5;${shownum}m color ${shownum} \E[0m"
}
done
echo
}
done
}
done
offset=232
for num1 in {0..23}
do {
shownum=`expr $offset + $num1`
echo -en "\E[0;48;5;${shownum}m ${shownum}\E[0m"
}
done
echo

View File

@ -30,7 +30,7 @@ done | sort # Otherwise file list is unsorted.
# As Dominik 'Aeneas' Schnitzer points out,
#+ failing to quote $( find $directory -type l )
#+ will choke on filenames with embedded whitespace.
# Even this will only pick up the first field of each argument.
# containing whitespace.
exit 0

View File

@ -0,0 +1,39 @@
#!/bin/bash
# test-suite.sh
# A partial Bash compatibility test suite.
# Double brackets (test)
String="Double brackets supported?"
echo -n "Double brackets test: "
if [[ "$String" = "Double brackets supported?" ]]
then
echo "PASS"
else
echo "FAIL"
fi
# Double brackets and regex matching
String="Regex matching supported?"
echo -n "Regex matching: "
if [[ "$String" =~ R.....matching* ]]
then
echo "PASS"
else
echo "FAIL"
fi
# Arrays
test_arr=FAIL
Array=( If supports arrays will print PASS )
test_arr=${Array[5]}
echo "Array test: $test_arr"
# Completing this script is an exercise for the reader.
# Add to the above similar tests for double parentheses,
#+ brace expansion, $() command substitution, etc.
exit $?

View File

@ -1,14 +1,15 @@
#!/bin/bash
# unset.sh: Unsetting a variable.
variable=hello # Initialized.
variable=hello # Initialized.
echo "variable = $variable"
unset variable # Unset.
# Same effect as: variable=
echo "(unset) variable = $variable" # $variable is null.
unset variable # Unset.
# In this particular context,
#+ same effect as: variable=
echo "(unset) variable = $variable" # $variable is null.
if [ -z "$variable" ] # Try a string-length test.
if [ -z "$variable" ] # Try a string-length test.
then
echo "\$variable has zero length."
fi

View File

@ -26,7 +26,7 @@ done < <( echo "random input" )
# ^ ^
echo "\$global (using process substitution) = $global"
# random input
# Random input
# $global (using process substitution) = 3D: Available outside the loop.
@ -60,6 +60,6 @@ do
# It does *not* run in a subshell, so ...
done < <( cat $0 )
echo "OUTPUT = "
echo ${outloop[*]} # ... the entire script echoes.
echo ${outloop[*]} # ... the entire script echoes.
exit $?

View File

@ -1215,7 +1215,7 @@ DVD drive. </Para>
Ecology-HOWTO</ULink>,
<CiteTitle>Linux Ecology HOWTO</CiteTitle>
</Para><Para>
<CiteTitle>Updated: Jun 2007</CiteTitle>.
<CiteTitle>Updated: Aug 2009</CiteTitle>.
Discusses ways to make computers less harmful to
our environment and to solve some ecological issues. It explains how to use
Linux to save power and consumables like paper and ink. Since it does not

View File

@ -375,7 +375,7 @@ Yes, Linux DOES make coffee, and it tastes good. </Para>
Ecology-HOWTO</ULink>,
<CiteTitle>Linux Ecology HOWTO</CiteTitle>
</Para><Para>
<CiteTitle>Updated: Jun 2007</CiteTitle>.
<CiteTitle>Updated: Aug 2009</CiteTitle>.
Discusses ways to make computers less harmful to
our environment and to solve some ecological issues. It explains how to use
Linux to save power and consumables like paper and ink. Since it does not