diff --git a/LDP/guide/docbook/abs-guide/Change.log b/LDP/guide/docbook/abs-guide/Change.log index 8c23eb79..257a1830 100644 --- a/LDP/guide/docbook/abs-guide/Change.log +++ b/LDP/guide/docbook/abs-guide/Change.log @@ -3,7 +3,141 @@ RELEASE HISTORY Change log -Version 1.4 +Version 1.5 (major update) +'PAPAYA' release +07/13/02 + +1) In "Basic Commands" section of "External Commands and Filters" + Added "man, info" entry. + At "ls," added comments to "ex40.sh" example. + +2) In "File and Archiving Commands" section of "External Commands and Filters" + section: + Moved "shred" to "Utilities" subsection and did minor rewriting of entry. + Fixed minor error in "de-rpm.sh" example. + Added "mktemp" entry. + Added "rpm" entry, with usage examples. + Added "rpm2cpio" entry. + +3) In "Math Commands" section of "External Commands" chapter: + Split "bc" and "dc" into separate entries. + At "bc", added "cannon.sh" example. + +4) In "Miscellaneous Commands" section of "External Commands" Chapter: + At "mcookie" entry, added "tempfile-name.sh" example. + At "seq" entry, added section to "ex53.sh" example. + Added "units" entry, with "unit-conversion.sh" example. + Added "doexec" entry. + More info at "pathchk" entry. + +5) In "Communications Commands" section of "External Commands" chapter: + Added usage example at "host" entry. + Revised "finger" entry. + Added "ipcalc" entry. + Added "mailto" entry. + Added "wget" entry. + Added "lynx" (with "-dump" option) entry. + More info at "nslookup." + More info at "dig." + More info at "traceroute." + +6) In "Time/Date Commands" section of "External Commands" chapter: + More info at "usleep" entry. + +7) In "Terminal Control Commands" section of "External Commands" chapter: + Added more options at "tput" entry. + Added "infocmp" entry, with usage example. + +8) In "File and Archive Commands" section of "External Commands" Chapter: + Added info at "diff" entry. + +9) In "Complex Commands" section of "External Commands" Chapter: + At "find" entry, clarified introductory remarks, and added info. + +10) In "Internal Commands and Builtins" chapter: + At "source" entry, added "self-source.sh" example. + At "shopt" entry, fixed up usage example. + +11) In "Job Control Commands" section of "Internal Commands": + Added comments to "self-destruct.sh" example. + +12) In "Testing and Branching" subsection of "Loops and Branches" chapter, + Improved "isalpha.sh" example (added integer test function). + +13) In "System and Administrative Commands" chapter: + Added "passwd" entry, with in-line illustrative script. + Added "readelf" entry. + Added "size" entry. + More discussion in "Modules" subsection. + Added usage example at "dmesg" entry. + +14) In "Assorted Tips" section of "Miscellany" chapter: + Added "Colorizing Scripts" section, with "ex30a.sh" and + "color-echo.sh" examples. + Added "agram.sh" example of iterated piping to a filter. + +15) In "Optimizations" section of "Miscellany" chapter: + Added "avoiding unnecessary commands." + +16) In "Arrays" chapter: + Added "poem.sh" example. + +17) In "Regular Expressions" chapter: + Clarifications and error corrections on "Extended Regular Expressions" + section (thanks, Peter Tillier). + +18) In "Tests" chapter: + Added code to "arith-tests.sh" example. + +19) In "Parameter Substitution" chapter: + At "${parameter-default}", added usage when command-line parameters in a + script are "missing." + At "${paramter?err_msg}", added "usage-msg.sh" example. + +20) In "Functions" chapter: + Added info to "ex60.sh" example. + +21) In "Gotchas" chapter: + Added material to "badread.sh" example. + +22) In "Special Characters" chapter: + Added usage examples at "*" entry. + +23) In "Variable Substitution" section of "Introduction to Variables" chapter: + Added in-line example of using uninitialized variable in arithmetic + operations. + +24) In "Bash Variables are Untyped" section of "Introduction to Variables" + chapter: + Rewrote "int-or-string.sh" example. + +25) Renamed "Oddities" section of "Miscellany" chapter to "Recursion", + and moved it forward. + +26) In "Starting off with a Sha-Bang" chapter: + Added commentary and script snippet to footnote [2]. + +27) Slight revision to introduction to the book. + +28) In "Contributed Scripts" appendix: + Added "soundex.sh" example. + Fixed minor typo in lead-in to "obj-oriented.sh" example. + +29) In "Writing Scripts" section of "Exercises" appendix: + Added "Justification" exercise to "Intermediate" section. + Added "Buffon's Needle" exercise to "Difficult" section. + Added "Chasing Spammers" exercise to "Difficult" section. + +30) In "Bibliography" section: + Added Steve Parker entry. + +31) Added Landon Noll epigraph to end of "Scripting With Style" chapter. + +32) Various minor cleanups and additions to example scripts. + + + +Version 1.4 (minor update) 'MANGO' release 06/16/02 @@ -105,7 +239,6 @@ Version 1.3 Added "sum matching numbers" exercise. 5) In "Oddities" section of "Miscellany" chapter: - Added "Security Issues" section. Added Rick Boivie's "pb.sh" script as a recursive script example. 6) In "Optimizations" section of "Miscellany" chapter: @@ -212,18 +345,21 @@ Version 1.3 30) Fixed reference links to "startup files" section. -31) In "Bibliography" section: +31) In "Miscellany" Chapter: + Added "Security Issues" section. + +32) In "Bibliography" section: Added Denning entry. Added Polya entry. Added "Shell Corner" entry. Added "UNIX Grymoire" entry. -32) In "Copyright" appendix: +33) In "Copyright" appendix: Clarified license terms with reference to "Open Publication License." -33) Various minor fixups and enhancements to example scripts. +34) Various minor fixups and enhancements to example scripts. -34) Updated references to LDP site (changed from 'linuxdoc.org' to +35) Updated references to LDP site (changed from 'linuxdoc.org' to 'tldp.org'). diff --git a/LDP/guide/docbook/abs-guide/abs-guide.sgml b/LDP/guide/docbook/abs-guide/abs-guide.sgml index 48aed247..79bfc00b 100644 --- a/LDP/guide/docbook/abs-guide/abs-guide.sgml +++ b/LDP/guide/docbook/abs-guide/abs-guide.sgml @@ -37,6 +37,7 @@ Uncomment line below to generate index. + @@ -253,6 +254,15 @@ Uncomment line below to generate index. + + + + + + + + + @@ -273,8 +283,8 @@ Uncomment line below to generate index. - 1.4 - 16 June 2002 + 1.5 + 13 July 2002 @@ -355,6 +365,14 @@ Uncomment line below to generate index. and scripts added. + + 1.5 + 13 July 2002 + mc + 'PAPAYA' release: A few bugfixes, much more material + and scripts added. + + @@ -375,7 +393,7 @@ Uncomment line below to generate index. linkend="bzipref">bzip2-ed tarball including both the SGML source and rendered HTML, may be downloaded from + url="http://personal.riverusers.com/~thegrendel/abs-guide-1.5.tar.bz2"> the author's home site. See the change log for a revision history. @@ -523,16 +541,16 @@ Uncomment line below to generate index. have been merged into Bash. and the C Shell and its variants. (Note that C Shell programming - is not recommended due to certain inherent problems, as pointed - out in a news - group posting by Tom Christiansen in October of 1993). + is not recommended due to certain inherent problems, as pointed out + in an October, 1993 Usenet + posting by Tom Christiansen). - The following is a tutorial in shell scripting. It relies - heavily on examples to illustrate features of the shell. + What follows is a tutorial on shell scripting. It relies + heavily on examples to illustrate various features of the shell. As far as possible, the example scripts have been tested, - and some of them may actually be useful in real life. The + and some of them may even be useful in real life. The reader should use the actual examples in the source archive (something-or-other.sh), @@ -618,14 +636,31 @@ Uncomment line below to generate index. whether it be a shell, a programming language, or a utility. This command interpreter then executes the commands in the script, starting at the top (line 1 of the script), ignoring comments. - The #! line in a shell script + + + The #! line in a shell script will be the first thing the command interpreter (sh or bash) sees. Since this line begins with a #, it will be correctly interpreted as a comment when the command interpreter finally executes the script. The line has already served its purpose - calling the command - interpreter. + interpreter. + If, in fact, the script includes an + extra #! line, then + bash will interpret it as a comment. + #!/bin/bash + +echo "Part 1 of script." +a=1 + +#!/bin/bash +# This does *not* launch a new script. + +echo "Part 2 of script." +echo $a # Value of $a stays at 1. + + @@ -677,13 +712,14 @@ exit $WHATEVER # Doesn't matter. The script will not exit here.#! can be omitted if the script consists only of a set of generic system commands, using no internal - shell directives. Example 2, above, requires the initial - #!, since the variable assignment line, + shell directives. The second example, above, requires the + initial #!, since the variable assignment line, lines=50, uses a shell-specific construct. Note that #!/bin/sh invokes the default shell interpreter, which defaults to /bin/bash on a Linux machine. + This tutorial encourages a modular approach to constructing a script. Make note of and collect boilerplate code snippets that might be useful @@ -1443,12 +1479,20 @@ fi [asterisk] The * character serves as a wild card for filename expansion in - globbing, as well as - representing any number (or zero) characters in a regular expression. - + globbing. By itself, + it matches every filename in a given directory. + + bash$ echo * +abs-book.sgml add-drive.sh agram.sh alias.sh + + + + The * also represents any number + (or zero) characters in a regular expression. + @@ -2852,10 +2896,28 @@ echo; echo &ex9; - An uninitialized variable has a + + + An uninitialized variable has a null value - no assigned value at all (not zero!). Using a variable before assigning a value - to it will inevitably cause problems. + to it will usually cause problems. + + It is nevertheless possible to perform arithmetic operations + on an uninitialized variable. + + echo "$uninitialized" # (blank line) +let "uninitialized += 5" # Add 5 to it. +echo "$uninitialized" # 5 + +# Conclusion: +# An uninitialized variable has no value, however +#+ it acts as if it were 0 in an arithmetic operation. +# This is undocumented (and probably non-portable) behavior. + + See also . + + @@ -2930,9 +2992,9 @@ arch=$(uname -m) Untyped variables are both a blessing and a curse. They permit - more flexibility in scripting (enough rope to hang yourself) and make - it easier to grind out lines of code. However, they permit errors to - creep in and encourage sloppy programming habits. + more flexibility in scripting (enough rope to hang yourself!) and + make it easier to grind out lines of code. However, they permit + errors to creep in and encourage sloppy programming habits. The burden is on the programmer to keep track of what type the script variables are. Bash will not do it for you. @@ -3023,7 +3085,7 @@ arch=$(uname -m) - positional parameters + positional parameters parameter positional @@ -5140,12 +5202,12 @@ echo "t2 = $t2 a = $a" # t2 = 5 a = 9 0 is octal (base 8). A number preceded by 0x is hexadecimal (base 16). A number - with an embedded # is evaluated as - BASE#NUMBER (this option is of limited - usefulness because of range restrictions). + with an embedded # evaluates as + BASE#NUMBER (with range and notational + restrictions). - Representation of numerical constants<token>:</token> + Representation of numerical constants &numbers; @@ -5658,7 +5720,7 @@ echo "Last command argument processed = $last_cmd_arg" machine type Identifies the system hardware. bash$ echo $MACHTYPE -i686-debian-linux-gnu +i686 @@ -5699,7 +5761,7 @@ echo "Last command argument processed = $last_cmd_arg" operating system type bash$ echo $OSTYPE -linux-gnu +linux @@ -6308,7 +6370,8 @@ echo "$@" # 3 4 5 flags - Flags passed to script + Flags passed to script (using set). See . This was originally a ksh construct adopted into Bash, and unfortunately it does not seem to work reliably in Bash scripts. One possible use @@ -6384,7 +6447,7 @@ echo $_ # : exit status - exit status + Exit status of a command, function, or the script itself (see ) @@ -6403,10 +6466,13 @@ echo $_ # : PID of script - process id of the script itself, often used - in scripts to construct unique temp file names - (see , , , and ) + Process id of the script itself. The + $$ variable often finds use + in scripts to construct unique + temp file names (see , , , and ). This is usually simpler than + invoking mktemp. @@ -6977,20 +7043,37 @@ echo "New \$PATH = $PATH" ${parameter-default} + ${parameter:-default} If parameter not set, use default. echo ${username-`whoami`} # Echoes the result of `whoami`, if variable $username is still unset. - This is almost equivalent to - ${parameter:-default}. The - extra : makes a difference only when - parameter has been declared, - but is null. + ${parameter-default} + and ${parameter:-default} + are almost equivalent. The extra : makes + a difference only when parameter + has been declared, but is null. + + ¶msub; + + The default parameter construct + finds use in providing missing command-line + arguments in scripts. + + + DEFAULT_FILENAME=generic.data +filename=${1:-$DEFAULT_FILENAME} +# If not otherwise specified, the following command block operates +#+ on the file "generic.data". +# +# Commands follow. + + + See also , , and . - ¶msub; - @@ -7076,9 +7159,16 @@ echo "a = $a" # a = xyz - Using param substitution and <token>:</token> + Using parameter substitution and error messages &ex6; + + + Parameter substitution and <quote>usage</quote> messages + &usagemessage; + + + Parameter substitution and/or expansion @@ -7617,8 +7707,9 @@ echo "number = $number" # number = 0 During each pass through the loop, - arg takes on the value of each - variable in the list. + arg takes on the + value of each successive variable in the + list. for arg in "$var1" "$var2" "$var3" ... "$varN" # In pass 1 of the loop, $arg = $var1 @@ -9067,21 +9158,36 @@ shift $(($OPTIND - 1)) . - This command, when invoked from the command line, executes a script. Within - a script, a source file-name loads the file - file-name. This is the - shell scripting equivalent of a C/C++ #include - directive. It is useful in situations when multiple scripts use a - common data file or function library. + + + This command, when invoked from the command line, + executes a script. Within a script, a + source file-name loads the file + file-name. This is the shell scripting + equivalent of a C/C++ #include + directive. It is useful in situations when multiple scripts + use a common data file or function library. <quote>Including</quote> a data file &ex38; - File data-file for , above. - Must be present in same directory. + + File data-file for , above. Must be present in same + directory. + &ex38bis; + It is even possible for a script to + source itself, though this does not + seem to have any practical applications. + + + A (useless) script that sources itself + &selfsource; + + @@ -9100,7 +9206,7 @@ shift $(($OPTIND - 1)) exit command may optionally take an integer argument, which is returned to the shell as the exit status - of the script. It is a good practice to end all but the + of the script. It is good practice to end all but the simplest scripts with an exit 0, indicating a successful run. @@ -9176,8 +9282,11 @@ shift $(($OPTIND - 1)) version 2 or later of Bash. shopt -s cdspell -# Allows minor misspelling directory names with 'cd' -command. +# Allows minor misspelling of directory names with 'cd' + +cd /hpme # Oops! Mistyped '/home'. +pwd # /home + # The shell corrected the misspelling. @@ -10065,16 +10174,45 @@ chmod u+s filename the linked file by more than one name and is a superior alternative to aliasing (see ). - ln -s oldfile newfile - links the previously existing - oldfile to the newly created link, - newfile. + ln -s oldfile newfile + links the previously existing + oldfile to the newly created link, + newfile. + + man + info + + man + + + command + man + + + info + + + command + info + + + + These commands access the manual and information pages on + system commands and installed utilities. When available, the + info pages usually contain a more detailed + description than do the man pages. + + + + + + @@ -10113,14 +10251,14 @@ chmod u+s filename -exec COMMAND \; Carries out COMMAND on - each file that find scores a hit - on. COMMAND terminates - with \; (the ; - is escaped to make certain the shell passes it to - find literally, which concludes the - command sequence). If COMMAND + each file that find matches. + The command sequence terminates with \; + (the ; is escaped to make certain + the shell passes it to find + literally). If COMMAND contains {}, then find - substitutes the full path name of the selected file. + substitutes the full path name of the selected file for + {}. bash$ find ~/ -name '*.txt' @@ -10132,8 +10270,22 @@ chmod u+s filename find /home/bozo/projects -mtime 1 -# Lists all files in /home/bozo/projects directory tree -# that were modified within the last day. +# Lists all files in /home/bozo/projects directory tree +#+ that were modified within the last day. +# +# mtime = last modification time of the target file +# ctime = last status change time (via 'chmod' or otherwise) +# atime = last access time + +DIR=/home/bozo/junk_files +find "$DIR" -type f -atime +5 -exec rm {} \; +# Deletes all files in "/home/bozo/junk_files" +#+ that have not been accessed in at least 5 days. +# +# "-type filetype", where +# f = regular file +# d = directory, etc. +# (The 'find' manpage has a complete listing.) @@ -10154,9 +10306,9 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ - The option to + The option to find should not be confused with the exec shell builtin. + linkend="execref">exec shell builtin. <command>Badname</command>, eliminate file names @@ -10352,19 +10504,18 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ </variablelist> - <note> - <para>The above example illustrates how + <para>This example illustrates how <command>expr</command> uses the <emphasis>escaped parentheses -- \( ... \) --</emphasis> grouping operator in tandem with <link linkend="regexref">regular expression</link> parsing to match a substring.</para> - </note> - <para><link linkend="perlref">Perl</link> and - <link linkend="sedref">sed</link> have far superior string - parsing facilities. A short <command>Perl</command> or - <command>sed</command> <quote>subroutine</quote> within + <para><link linkend="perlref">Perl</link>, + <link linkend="sedref">sed</link>, and <link + linkend="awkref">awk</link> have far superior string + parsing facilities. A short <command>sed</command> or + <command>awk</command> <quote>subroutine</quote> within a script (see <xref linkend="wrapper">) is an attractive alternative to using <command>expr</command>.</para> @@ -10381,7 +10532,7 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ <title>Time / Date Commands - <anchor id="tdlisting1">Manipulating the time and date + <anchor id="tdlisting1">Time/date and timing date @@ -10596,9 +10747,10 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ This is the shell equivalent of a wait loop. It pauses for a - specified number of seconds, doing nothing. This can be useful for - timing or in processes running in the background, checking for a - specific event every so often (see ). + specified number of seconds, doing nothing. It can be useful + for timing or in processes running in the background, + checking for a specific event every so often (polling), + as in . sleep 3 # Pauses 3 seconds. @@ -10621,14 +10773,20 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ Microsleep (the u - may be read as the Greek mu, or micro + may be read as the Greek mu, or micro- prefix). This is the same as sleep, above, but sleeps in microsecond - intervals. This can be used for fine-grain timing, or for - polling an ongoing process at very frequent intervals. + intervals. It can be used for fine-grain timing, or for + polling an ongoing process at very frequent intervals. + + usleep 30 # Pauses 30 microseconds. + + This command is part of the Red Hat initscripts / + rc-scripts package. + The usleep command does not provide particularly accurate timing, and is therefore unsuitable for critical timing loops. @@ -11936,8 +12094,70 @@ tr -d 0-9 <filename Creation and manipulation utility for archives, mainly used for binary object file libraries. - + + + rpm + + rpm + + + command + package manager + + + + The Red Hat Package Manager, or + rpm utility provides a wrapper for + source or binary archives. It includes commands for + installing and checking the integrity of packages, among + other things. + + A simple rpm -i package_name.rpm + usually suffices to install a package, though there are many + more options available. + + + An rpm -qa gives a + complete list of all installed rpm packages + on a given system. An rpm -qa package_name + lists only the package(s) corresponding to + package_name. + + + +bash$ rpm -qa +redhat-logos-1.1.3-1 + glibc-2.2.4-13 + cracklib-2.7-12 + dosfstools-2.7-1 + gdbm-1.8.0-10 + ksymoops-2.4.1-1 + mktemp-1.5-11 + perl-5.6.0-17 + reiserfs-utils-3.x.0j-2 + ... + + +bash$ rpm -qa docbook-utils +docbook-utils-0.6.9-2 + + +bash$ rpm -qa docbook | grep docbook +docbook-dtd31-sgml-1.0-10 + docbook-style-dsssl-1.64-3 + docbook-dtd30-sgml-1.0-10 + docbook-dtd40-sgml-1.0-11 + docbook-utils-pdf-0.6.9-2 + docbook-dtd41-sgml-1.0-10 + docbook-utils-0.6.9-2 + + + + + + + cpio @@ -11959,7 +12179,24 @@ tr -d 0-9 <filename Using <command>cpio</command> to move a directory tree &ex48; - + + + + + + rpm2cpio + + rpm + + + command + cpio + + + This command extracts a + cpio archive from an rpm one. + Unpacking an <emphasis>rpm</emphasis> archive &derpm; @@ -12307,27 +12544,6 @@ tr -d 0-9 <filename - - shred - - shred - - - command - secure delete - - - Securely erase a file by overwriting it multiple times with - random bit patterns before deleting it. This command has - the same effect as , but does it - in a more thorough and elegant manner. - This is one of the GNU fileutils. - Using shred on a file may - not prevent recovery of some or all of its contents using - advanced forensic technology. - - - locate slocate @@ -12424,8 +12640,10 @@ tr -d 0-9 <filename line belongs to. The option to - diff outputs each compared file, line by line, - in separate columns, with non-matching lines marked. + diff outputs each compared file, line by + line, in separate columns, with non-matching lines marked. The + and options likewise + make the output of the command easier to interpret. There are available various fancy frontends for diff, such as spiff, @@ -12747,6 +12965,31 @@ gzip -cd patchXX.gz | patch -p0 + + shred + + shred + + + command + secure delete + + + + Securely erase a file by overwriting it multiple times with + random bit patterns before deleting it. This command has + the same effect as , but does it + in a more thorough and elegant manner. + + This is one of the GNU fileutils. + + Advanced forensic technology may still be able to + recover the contents of a file, even after application of + shred. + + + + @@ -12862,6 +13105,28 @@ gzip -cd patchXX.gz | patch -p0 <anchor id="famisc1">Miscellaneous + + mktemp + + temporary + + + command + filename + + + Create a temporary file with a unique + filename. + PREFIX=filename +tempfile=`mktemp $PREFIX.XXXXXX` +# ^^^^^^ Need at least 6 placeholders +#+ in the filename template. +echo "tempfile name = $tempfile" +# tempfile name = filename.QA2ZpY +# or something similar... + + + make @@ -12952,6 +13217,9 @@ gzip -cd patchXX.gz | patch -p0 Communications Commands + Certain of the following commands find use in chasing spammers, as well as in + network data transfer and analysis. <anchor id="communinfo1">Information and Statistics @@ -12968,24 +13236,36 @@ gzip -cd patchXX.gz | patch -p0 Searches for information about an Internet host by name or IP address, using DNS. + + bash$ host surfacemail.com +surfacemail.com. has address 202.92.42.236 + + - vrfy + ipcalc - vrfy + ipcalc command - vrfy + ipcalc - Verify an Internet e-mail address. + Carries out IP address lookups. + With the option, + ipcalc does a reverse DNS lookup, finding + the name of the host (server) from the IP address. + + bash$ ipcalc -h 202.92.42.236 +HOSTNAME=surfacemail.com + + - nslookup @@ -12996,9 +13276,28 @@ gzip -cd patchXX.gz | patch -p0 name server lookup - Do an Internet name server lookup on a host - by IP address. This may be run either interactively or - noninteractively, i.e., from within a script. + + Do an Internet name server lookup + on a host by IP address. This is essentially equivalent + to ipcalc -h or dig -x + . The command may be run either interactively + or noninteractively, i.e., from within a script. + + The nslookup command has allegedly + been deprecated, but it still has its + uses. + + + bash$ nslookup -sil 66.97.104.180 +nslookup kuhleersparnis.ch + Server: 135.116.137.2 + Address: 135.116.137.2#53 + + Non-authoritative answer: + Name: kuhleersparnis.ch + + + @@ -13012,10 +13311,36 @@ gzip -cd patchXX.gz | patch -p0 domain information groper + Similar to nslookup, do an Internet name server lookup on a host. May be run either interactively or noninteractively, i.e., from within a script. + + Compare the output of dig -x with + ipcalc -h and + nslookup. + + + bash$ dig -x 81.9.6.2 +;; Got answer: + ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 11649 + ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 + + ;; QUESTION SECTION: + ;2.6.9.81.in-addr.arpa. IN PTR + + ;; AUTHORITY SECTION: + 6.9.81.in-addr.arpa. 3600 IN SOA ns.eltel.net. noc.eltel.net. + 2002031705 900 600 86400 3600 + + ;; Query time: 537 msec + ;; SERVER: 135.116.137.2#53(135.116.137.2) + ;; WHEN: Wed Jun 26 08:35:24 2002 + ;; MSG SIZE rcvd: 91 + + + @@ -13029,12 +13354,24 @@ gzip -cd patchXX.gz | patch -p0 traceroute + Trace the route taken by packets sent to a remote host. This command works within a LAN, WAN, or over the Internet. The remote host may be specified by an IP address. The output of this command may be filtered by grep or sed in a pipe. + + + bash$ traceroute 81.9.6.2 +traceroute to 81.9.6.2 (81.9.6.2), 30 hops max, 38 byte packets + 1 tc43.xjbnnbrb.com (136.30.178.8) 191.303 ms 179.400 ms 179.767 ms + 2 or0.xjbnnbrb.com (136.30.178.1) 179.536 ms 179.534 ms 169.685 ms + 3 192.168.11.101 (192.168.11.101) 189.471 ms 189.556 ms * + ... + + + @@ -13103,14 +13440,23 @@ gzip -cd patchXX.gz | patch -p0 - Retrieve information about a particular user on - a network. Optionally, this command can display - the user's ~/.plan, + Retrieve information about users on a + network. Optionally, this command can display + a user's ~/.plan, ~/.project, and ~/.forward files, if present. - bash$ finger bozo + +bash$ finger +Login Name Tty Idle Login Time Office Office Phone + bozo Bozo Bozeman tty1 8 Jun 25 16:59 + bozo Bozo Bozeman ttyp0 Jun 25 16:59 + bozo Bozo Bozeman ttyp1 Jun 25 17:07 + + + +bash$ finger bozo Login: bozo Name: Bozo Bozeman Directory: /home/bozo Shell: /bin/bash On since Fri Aug 31 20:13 (MST) on tty1 1 hour 38 minutes idle @@ -13141,6 +13487,20 @@ gzip -cd patchXX.gz | patch -p0 + + vrfy + + vrfy + + + command + vrfy + + + Verify an Internet e-mail address. + + + @@ -13279,6 +13639,45 @@ gzip -cd patchXX.gz | patch -p0 + + wget + + wget + + + command + download + + + The wget utility + non-interactively retrieves or + downloads files from a Web or ftp site. It works well in a + script. + wget -p http://www.xyz23.com/file01.html +wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -o $SAVEFILE + + + + + + lynx + + lynx + + + command + browser + + + The lynx Web and file browser + can be used inside a script (with the + option) to retrieve a file from a Web or + ftp site non-interactively. + lynx -dump http://www.xyz23.com/file01.html >$SAVEFILE + + + + rlogin @@ -13394,7 +13793,7 @@ gzip -cd patchXX.gz | patch -p0 - Send an e-mail message to a user. + Send or read e-mail messages. This stripped-down command-line mail client works fine as a command embedded in a script. @@ -13407,6 +13806,24 @@ gzip -cd patchXX.gz | patch -p0 + + mailto + + mailto + + + command + MIME mail + + + Similar to the mail command, + mailto sends e-mail messages + from the command line or in a script. However, + mailto also permits sending MIME + (multimedia) messages. + + + vacation @@ -13425,6 +13842,7 @@ gzip -cd patchXX.gz | patch -p0 + @@ -13453,8 +13871,10 @@ gzip -cd patchXX.gz | patch -p0 terminfo data. Various options permit certain terminal operations. tput clear is the equivalent of clear, - below. tput reset is the equivalent of - reset, below. + below. tput reset is the equivalent + of reset, below. tput + sgr0 also resets the terminal, but without + clearing the screen. bash$ tput longname @@ -13462,12 +13882,50 @@ gzip -cd patchXX.gz | patch -p0 + Issuing a tput cup X Y moves + the cursor to the (X,Y) coordinates in the current + terminal. A clear to erase the terminal + screen would normally precede this. + Note that stty offers a more powerful command set for controlling a terminal. + + infocmp + + infocmp + + + command + terminal + + + + This command prints out extensive information about the + current terminal. It references the + terminfo database. + + + bash$ infocmp +# Reconstructed via infocmp from file: + /usr/share/terminfo/r/rxvt + rxvt|rxvt terminal emulator (X Window System), + am, bce, eo, km, mir, msgr, xenl, xon, + colors#8, cols#80, it#8, lines#24, pairs#64, + acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, + bel=^G, blink=\E[5m, bold=\E[1m, + civis=\E[?25l, + clear=\E[H\E[2J, cnorm=\E[?25h, cr=^M, + ... + + + + + + reset @@ -13553,7 +14011,6 @@ gzip -cd patchXX.gz | patch -p0 bc - dc bc @@ -13561,29 +14018,23 @@ gzip -cd patchXX.gz | patch -p0 command bc - - dc - - - command - dc - - These are flexible, arbitrary precision calculation - utilities. - bc has a syntax vaguely resembling C. - dc is stack-oriented and uses RPN - (Reverse Polish Notation). - - Of the two, bc seems more useful in - scripting. It is a fairly well-behaved UNIX utility, and may - therefore be used in a pipe. Bash can't handle floating point calculations, and it lacks operators for certain important mathematical functions. Fortunately, bc comes 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. + + Since it is a fairly well-behaved UNIX utility, and may + therefore be used in a pipe, + bc comes in handy in scripts. + Here is a simple template for using bc to calculate a script variable. This uses command @@ -13638,6 +14089,31 @@ LIMIT_STRING &altbc; + + Calculating PI + &cannon; + + + + + + + dc + + dc + + + command + dc + + + + 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. + Most persons avoid dc, since it requires non-intuitive RPN input. Yet it has its uses. @@ -13767,7 +14243,7 @@ LIMIT_STRING parses command-line options preceded by a dash. This external command corresponds to the getopts - Bash builtin, but it is not nearly as flexible. + Bash builtin, but it is not nearly as versatile. Using <command>getopt</command> to parse command-line @@ -13838,10 +14314,11 @@ LIMIT_STRING <para><userinput>yes | rm -r dirname</userinput> has same effect as <userinput>rm -rf dirname</userinput> (careful!).</para> - <warning><para>Be very cautious when piping <command>yes</command> - to a potentially dangerous system command, such as - <link linkend="fsckref">fsck</link> or - <link linkend="fdiskref">fdisk</link>.</para></warning> + <warning><para>Caution advised when piping <command>yes</command> + to a potentially dangerous system command, such + as <link linkend="fsckref">fsck</link> or <link + linkend="fdiskref">fdisk</link>. It may have unintended + side-effects.</para></warning> </listitem> </varlistentry> @@ -14008,9 +14485,12 @@ LIMIT_STRING filename exceeds the maximum allowable length (255 characters) or one or more of the directories in its path is not searchable, then an error message - results. Unfortunately, <command>pathchk</command> does + results.</para> + + <para>Unfortunately, <command>pathchk</command> does not return a recognizable error code, and it is therefore - pretty much useless in a script.</para> + pretty much useless in a script. Consider instead the + <link linkend="rtif">file test operators</link>.</para> </listitem> </varlistentry> @@ -14188,10 +14668,39 @@ echo -n "hello world" | dd cbs=1 conv=unblock 2> /dev/null random001=`md5sum $0 | awk '{print $1}'` # Uses 'awk' to strip off the filename.</programlisting> </para> + + <para>The <command>mcookie</command> command gives yet another way + to generate a <quote>unique</quote> filename.</para> + + <example id="tempfilename"> + <title>Filename generator + &tempfilename; + + + units + + units + + + command + conversion + + + This utility converts between different units of measure. + While normally invoked in interactive mode, + units may find use in a script. + + Converting meters to miles + &unitconversion; + + + + + m4 @@ -14217,8 +14726,9 @@ random001=`md5sum $0 | awk '{print $1}'` linkend="awkref">awk, in addition to its extensive macro expansion facilities. - The April, 2002 issue of Linux - Journal has a very nice article on + The April, 2002 issue of Linux + Journal has a very nice article on m4 and its uses. @@ -14229,6 +14739,49 @@ random001=`md5sum $0 | awk '{print $1}'` + + doexec + + doexec + + + command + executable arg list + + + The doexec command enables passing + an arbitrary list of arguments to a binary + executable. In particular, passing + argv[0] (which corresponds to $0 in a script) lets the + executable be invoked by various names, and it can then + carry out different sets of actions, according to the name + by which it was called. What this amounts to is roundabout + way of passing options to an executable. + + For example, the /usr/local/bin directory might + contain a binary called aaa. Invoking + doexec /usr/local/bin/aaa list + would list all those files + in the current working directory beginning with an + a, while invoking (the same executable + with) doexec /usr/local/bin/aaa delete + would delete those files. + + The various behaviors of the executable + must be defined within the code of the executable itself, + analogous to something like the following in a shell script: + case `basename $0` in +"name1" ) do_something;; +"name2" ) do_something_else;; +"name3" ) do_yet_another_thing;; +* ) bail_out;; +esac + + + + @@ -14251,6 +14804,43 @@ random001=`md5sum $0 | awk '{print $1}'` <anchor id="usersgroups1">Users and Groups + + users + + users + + + command + users + + + Show all logged on users. This is the approximate + equivalent of who -q. + + + + + groups + + groups + + + command + groups + + + Lists the current user and the groups she belongs to. + This corresponds to the $GROUPS internal variable, + but gives the group names, rather than the numbers. + bash$ groups +bozita cdrom cdwriter audio xgrp + +bash$ echo $GROUPS +501 + + + chown chgrp @@ -14508,17 +15098,50 @@ sudo cp /root/secretfile /home/bozo/secret - users + passwd - users + passwd command - users + password - Show all logged on users. This is the approximate - equivalent of who -q. + + Sets or changes a user's password. + + The passwd can be used in a script, but + should not be. + #!/bin/bash +# set-new-password.sh: Not a good idea. +# This script must be run as root, +#+ or better yet, not run at all. + +ROOT_UID=0 # Root has $UID 0. +E_WRONG_USER=65 # Not root? + +if [ "$UID" -ne "$ROOT_UID" ] +then + echo; echo "Only root can run this script."; echo + exit $E_WRONG_USER +else + echo; echo "You should know better than to run this script, root." +fi + + +username=bozo +NEWPASSWORD=security_violation + +echo "$NEWPASSWORD" | passwd --stdin "$username" +# The '--stdin' option to 'passwd' permits +#+ getting new password from stdin (or a pipe). + +echo; echo "User $username's password changed!" + +# Using the 'passwd' command in a script is dangerous. + +exit 0 + @@ -14556,28 +15179,6 @@ sudo cp /root/secretfile /home/bozo/secret - - groups - - groups - - - command - groups - - - Lists the current user and the groups she belongs to. - This corresponds to the $GROUPS internal variable, - but gives the group names, rather than the numbers. - bash$ groups -bozita cdrom cdwriter audio xgrp - -bash$ echo $GROUPS -501 - - - newgrp @@ -14870,6 +15471,14 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< parsed with grep, sed, or awk from within a script. + + bash$ dmesg | grep hda +Kernel command line: ro root=/dev/hda2 + hda: IBM-DLGA-23080, ATA DISK drive + hda: 6015744 sectors (3080 MB) w/96KiB Cache, CHS=746/128/63 + hda: hda1 hda2 hda3 < hda5 hda6 hda7 > hda4 + + @@ -15367,6 +15976,54 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< + + readelf + + elf + + + command + statistics + + + Show information and statistics about a designated + elf binary. This is part of the + binutils package. + bash$ readelf -h /bin/bash +ELF Header: + Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 + Class: ELF32 + Data: 2's complement, little endian + Version: 1 (current) + OS/ABI: UNIX - System V + ABI Version: 0 + Type: EXEC (Executable file) + . . . + + + + + size + + size + + + command + segment + + + The size [/path/to/binary] command + gives the segment sizes of a binary executable or archive file. + This is mainly of use to programmers. + + bash$ size /bin/bash + text data bss dec hex filename + 495971 22496 17392 535859 82d33 /bin/bash + + + + + @@ -16282,8 +16939,8 @@ mount -o loop /dev/loop0 /mnt # Mount it. when running from an emergency boot floppy (chroot to /dev/fd0), or as an option to lilo when recovering - from a system crash. Other uses include installation - from a different filesystem (an rpm + from a system crash. Other uses include installation from a + different filesystem (an rpm option) or running a readonly filesystem from a CD ROM. Invoke only as root, and use with care. @@ -16556,6 +17213,8 @@ then pcmcia_core 45984 0 [serial_cs ds i82365] + Doing a cat /proc/modules gives the + same information. @@ -16569,8 +17228,9 @@ then insmod - Force installation of a kernel module. Must be invoked - as root. + Force installation of a kernel module (use + modprobe instead, when possible). Must + be invoked as root. @@ -16599,7 +17259,8 @@ then modprobe - Module loader that is normally invoked automatically in a startup script. + Module loader that is normally invoked automatically + in a startup script. Must be invoked as root. @@ -16613,7 +17274,8 @@ then depmod - Creates module dependency file, usually invoked from startup script. + Creates module dependency file, usually invoked from + startup script. @@ -16692,7 +17354,7 @@ print "even when I don't know where to find Perl.\n"; Remove the debugging symbolic references from an executable - binary. This decreases its size, but makes debugging of it + binary. This decreases its size, but makes debugging it impossible. This command often occurs in a Makefile, @@ -18007,6 +18669,7 @@ echo a111b | gawk '/a1+b/' brackets -- \{ \} -- indicate the number of occurrences of a preceding RE to match. + It is necessary to escape the curly brackets since they have only their literal character meaning otherwise. This usage is technically not part of the basic @@ -18015,20 +18678,25 @@ echo a111b | gawk '/a1+b/' [0-9]\{5\} matches exactly five digits (characters in the range of 0 to 9). - + Curly brackets are not available as an RE in the - classic version of awk. However, + classic (non-POSIX compliant) version + of awk. However, gawk has the option that permits them (without being escaped). + bash$ echo 2222 | gawk --re-interval '/2{3}/' 2222 - + Perl and some + egrep versions do not require escaping + the curly brackets. + + @@ -18069,6 +18737,11 @@ echo a111b | gawk '/a1+b/' + Some versions of sed, + ed, and ex support + escaped versions of the extended regular expressions + described above. + @@ -19461,6 +20134,11 @@ false && ( true || echo false ) # (nothing echoed) &ex66; + + Formatting a poem + &poem; + + Array variables have a syntax all their own, and even standard Bash commands and operators have special options adapted for array use. @@ -20873,6 +21551,15 @@ if COMMAND + + + Landon Noll + ... reading the UNIX source code to the Bourne shell (/bin/sh). I + was shocked at how much simple algorithms could be made cryptic, and + therefore useless, by a poor choice of code style. I asked myself, + Could someone be proud of this code? + + @@ -21108,6 +21795,188 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" # Greater ASCI + + Recursion + + Can a script recursively + call itself? Indeed. + + + A (useless) script that recursively calls itself + &recurse; + + + + A (useful) script that recursively calls itself + &pbook; + + + Too many levels of recursion can exhaust the + script's stack space, causing a segfault. + + + + + + <quote>Colorizing</quote> Scripts + + The ANSI + ANSI is, of course, the acronym for the American + National Standards Institute. + escape sequences set screen attributes, such as bold + text, and color of foreground and background. DOS batch files commonly used + ANSI escape codes for color output, + and so can Bash scripts. + + + A <quote>colorized</quote> address database + &ex30a; + + + The simplest, and perhaps most useful ANSI escape sequence is + bold text, \033[1m ... \033[0m. The + \033 represents an escape, + the [1 turns on the bold attribute, while the + [0 switches it off. The m terminates + each term of the escape sequence. + +bash$ echo -e "\033[1mThis is bold text.\033[0m" + + + + A similar escape sequence switches on the underline + attribute (on an rxvt and and an + aterm). + +bash$ echo -e "\033[4mThis is underlined text.\033[0m" + + + + With an echo, the + option enables the escape + sequences. + + Other escape sequences change the text and/or background color. + +bash$ echo -e '\E[34;47mThis prints in blue.'; tput sgr0 + + +bash$ echo -e '\E[33;44m'"yellow text on blue background"; tput sgr0 + + The tput sgr0 restores the terminal settings + to normal. Omitting this lets all subsequent output from that + particular terminal remain blue. + + + Use the following template for writing colored text on a colored + background. + + + echo -e '\E[COLOR1;COLOR2mSome text goes here.' + + + The \E[ begins the escape sequence. + The semicolon-separated numbers COLOR1 and + COLOR2 specify a foreground and a background + color, according to the table below. (The order of the + numbers does not matter, since the foreground and background + numbers fall in non-overlapping ranges.) The m + terminates the escape sequence, and the text begins immediately + after that. + + Note also that single quotes + enclose the remainder of the command sequence following the + echo -e. + + + + The numbers in the following table work for an + rxvt terminal. Results may vary for other + terminal emulators. + + + Numbers Representing Colors in Escape Sequences + + + + Color + Foreground + Background + + + + + + 30 + 40 + + + + 31 + 41 + + + + 32 + 42 + + + + 33 + 43 + + + + 34 + 44 + + + + 35 + 45 + + + + 36 + 46 + + + + 37 + 47 + + + +
+ + + Echoing colored text + &colorecho; + + + 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 greatly compromises + the usefulness of colorizing scripts, and + possibly relegates this technique to the status of a gimmick + or even a toy. + + Moshe Jacobson's color utility + (http://runslinux.net/projects/color) + considerably simplifies using ANSI escape sequences. It + substitutes a clean and logical syntax for the clumsy constructs + just discussed. + + +
+ + Optimizations @@ -21128,6 +21997,17 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" # Greater ASCI Use builtin commands in preference to system commands. Builtins execute faster and usually do not launch a subshell when invoked. + + Avoid unnecessary commands, particularly in a pipe. + cat "$file" | grep "$word" + +grep "$word" "$file" + +# The above command lines have an identical effect, +#+ but the second runs faster since it launches one fewer subprocess. + The cat command seems especially + prone to overuse in scripts. Use the time and times tools to profile @@ -21468,13 +22348,24 @@ echo "$newstring" # Each sentence should start with a capital letter.repeatedly feed the output of a filter (by piping) back to the same filter, but with a different set of arguments and/or options. Especially - suitable for this is tr. + suitable for this are tr and + grep. + # From "wstrings.sh" example. wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \ tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '` + + + Fun with anagrams + &agram; + + + See also , , and . + @@ -21529,27 +22420,6 @@ tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '` - - Oddities - - Can a script recursively - call itself? Indeed. - - - A (useless) script that recursively calls itself - &recurse; - - - - A (useful) script that recursively calls itself - &pbook; - - - Too many levels of recursion can exhaust the - script's stack space, causing a segfault. - - - Security Issues @@ -21844,7 +22714,7 @@ tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '` Likewise, thanks to Michel Charpentier for - permission to use his dc factoring script + permission to use his dc factoring script (). Kudos to + + + Steve Parker's Shell Programming + Stuff. + + + Example shell scripts at &makedict; + + Soundex conversion + &soundex; + + <quote>Game of Life</quote> &lifeslow; @@ -22626,7 +23509,7 @@ tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '` &string; - Stephane Chazelas demonstrates object-oriented programming a + Stephane Chazelas demonstrates object-oriented programming in a Bash script. @@ -23445,6 +24328,7 @@ history Converting DOS Batch Files to Shell Scripts + Quite a number of programmers learned scripting on a PC running DOS. Even the crippled DOS batch file language allowed writing some fairly powerful scripts and applications, though they often required @@ -24196,6 +25080,17 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 + + Justification + + Given ASCII text input either from + stdin or a file, by adjusting + the word spacing right-justify each line to a + user-specified line-width and send the output to + stdout. + + + Passwords @@ -24259,6 +25154,24 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 + + Chasing Spammers + + + Write a script that analyzes a spam e-mail by doing + DNS lookups on the IP addresses in the headers to identify + the relay hosts as well as the originating ISP. The + script will forward the unaltered spam message to the + responsible ISPs. Of course, it will be necessary to + filter out your own ISP's IP address, + so you don't end up complaining about yourself. + + As necessary, use the appropriate network analysis commands. + + + + Morse Code @@ -24385,6 +25298,34 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 + + Calculating PI using Buffon's Needle + + + The Eighteenth Century French mathematician de Buffon + came up with a novel experiment. Repeatedly drop a + needle of length n onto a wooden floor + composed of long and narrow parallel boards. The cracks + separating the equal-width floorboards are a fixed distance + d apart. Keep track of the total drops and + the number of times the needle intersects a crack on the + floor. The ratio of these two quantities turns out to be + a fractional multiple of PI. + + In the spirit of , write a + script that runs a Monte Carlo simulation of Buffon's + Needle. To simplify matters, set the needle length equal to + the distance between the cracks, n = d. + + Hint: there are actually two critical variables: + the distance from the center of the needle to the nearest + crack to it, and the angle of the needle to that crack. You + may use bc to handle the + calculations. + + + + Playfair Cipher diff --git a/LDP/guide/docbook/abs-guide/arith-tests.sh b/LDP/guide/docbook/abs-guide/arith-tests.sh index 8e97467b..30a9e340 100644 --- a/LDP/guide/docbook/abs-guide/arith-tests.sh +++ b/LDP/guide/docbook/abs-guide/arith-tests.sh @@ -5,15 +5,32 @@ # Exit status opposite from [ ... ] construct! (( 0 )) -echo "Exit status of \"(( 0 ))\" is $?." # 1 +echo "Exit status of \"(( 0 ))\" is $?." # 1 (( 1 )) -echo "Exit status of \"(( 1 ))\" is $?." # 0 +echo "Exit status of \"(( 1 ))\" is $?." # 0 -(( 5 > 4 )) # true -echo $? # 0 +(( 5 > 4 )) # true +echo "Exit status of \"(( 5 > 4 ))\" is $?." # 0 -(( 5 > 9 )) # false -echo $? # 1 +(( 5 > 9 )) # false +echo "Exit status of \"(( 5 > 9 ))\" is $?." # 1 + +(( 5 - 5 )) # 0 +echo "Exit status of \"(( 5 - 5 ))\" is $?." # 1 + +(( 5 / 4 )) # Division o.k. +echo "Exit status of \"(( 5 / 4 ))\" is $?." # 0 + +(( 1 / 2 )) # Division result < 1. +echo "Exit status of \"(( 1 / 2 ))\" is $?." # Rounded off to 0. + # 1 + +(( 1 / 0 )) 2>/dev/null # Illegal division by 0. +echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1 + +# What effect does the "2>/dev/null" have? +# What would happen if it were removed? +# Try removing it, then rerunning the script. exit 0 diff --git a/LDP/guide/docbook/abs-guide/badread.sh b/LDP/guide/docbook/abs-guide/badread.sh index 04240806..d74fd551 100644 --- a/LDP/guide/docbook/abs-guide/badread.sh +++ b/LDP/guide/docbook/abs-guide/badread.sh @@ -10,6 +10,7 @@ c=ccc echo "one two three" | read a b c # Try to reassign a, b, and c. +echo echo "a = $a" # a = aaa echo "b = $b" # b = bbb echo "c = $c" # c = ccc @@ -29,4 +30,26 @@ echo "b = $b" # b = two echo "c = $c" # c = three # Reassignment succeeded. +# ------------------------------ + +# Note also that an echo to a 'read' works within a subshell. +# However, the value of the variable changes *only* within the subshell. + +a=aaa # Starting all over again. +b=bbb +c=ccc + +echo; echo +echo "one two three" | ( read a b c; +echo "Inside subshell: "; echo "a = $a"; echo "b = $b"; echo "c = $c" ) +# a = one +# b = two +# c = three +echo "-----------------" +echo "Outside subshell: " +echo "a = $a" # a = aaa +echo "b = $b" # b = bbb +echo "c = $c" # c = ccc +echo + exit 0 diff --git a/LDP/guide/docbook/abs-guide/collatz.sh b/LDP/guide/docbook/abs-guide/collatz.sh index 65927b4e..5c320346 100644 --- a/LDP/guide/docbook/abs-guide/collatz.sh +++ b/LDP/guide/docbook/abs-guide/collatz.sh @@ -20,22 +20,16 @@ #+ an operation that feeds its output back into the input. # Sometimes the result is a "chaotic" series. -ARGS=1 -E_BADARGS=65 - -if [ $# -ne $ARGS ] # Need a seed number. -then - echo "Usage: `basename $0` NUMBER" - exit $E_BADARGS -fi MAX_ITERATIONS=200 # For large seed numbers (>32000), increase MAX_ITERATIONS. -h=$1 # Seed +h=${1:-$$} # Seed + # Use $PID as seed, + #+ if not specified as command-line arg. echo -echo "C($1) --- $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/de-rpm.sh b/LDP/guide/docbook/abs-guide/de-rpm.sh index 4ce66955..af668c00 100644 --- a/LDP/guide/docbook/abs-guide/de-rpm.sh +++ b/LDP/guide/docbook/abs-guide/de-rpm.sh @@ -1,19 +1,20 @@ #!/bin/bash # de-rpm.sh: Unpack an 'rpm' archive -E_NO_ARGS=65 +: ${1?"Usage: `basename $0` target-file"} +# Must specify 'rpm' archive name as an argument. + + TEMPFILE=$$.cpio # Tempfile with "unique" name. # $$ is process ID of script. -if [ -z "$1" ] -then - echo "Usage: `basename $0` filename" -exit $E_NO_ARGS -fi - - rpm2cpio < $1 > $TEMPFILE # Converts rpm archive into cpio archive. cpio --make-directories -F $TEMPFILE -i # Unpacks cpio archive. rm -f $TEMPFILE # Deletes cpio archive. exit 0 + +# Exercise: +# Add check for whether 1) "target-file" exists and +#+ 2) it is really an rpm archive. +# Hint: parse output of 'file' command. diff --git a/LDP/guide/docbook/abs-guide/ex13.sh b/LDP/guide/docbook/abs-guide/ex13.sh index 01781353..858f6187 100644 --- a/LDP/guide/docbook/abs-guide/ex13.sh +++ b/LDP/guide/docbook/abs-guide/ex13.sh @@ -11,6 +11,8 @@ b=5 #+ whose value consists of all-integer characters. # Caution advised. +echo + if [ "$a" -ne "$b" ] then echo "$a is not equal to $b" @@ -23,9 +25,11 @@ if [ "$a" != "$b" ] then echo "$a is not equal to $b." echo "(string comparison)" + # "4" != "5" + # ASCII 52 != ASCII 53 fi -# In this instance, both "-ne" and "!=" work. +# In this particular instance, both "-ne" and "!=" work. echo diff --git a/LDP/guide/docbook/abs-guide/ex15.sh b/LDP/guide/docbook/abs-guide/ex15.sh index 08149521..b0bb8990 100644 --- a/LDP/guide/docbook/abs-guide/ex15.sh +++ b/LDP/guide/docbook/abs-guide/ex15.sh @@ -1,4 +1,5 @@ #!/bin/bash +# Naked variables echo @@ -7,16 +8,16 @@ echo # Assignment a=879 -echo "The value of \"a\" is $a" +echo "The value of \"a\" is $a." # Assignment using 'let' let a=16+5 -echo "The value of \"a\" is now $a" +echo "The value of \"a\" is now $a." echo # In a 'for' loop (really, a type of disguised assignment) -echo -n "The values of \"a\" in the loop are " +echo -n "Values of \"a\" in the loop are: " for a in 7 8 9 11 do echo -n "$a " @@ -28,7 +29,7 @@ echo # In a 'read' statement (also a type of assignment) echo -n "Enter \"a\" " read a -echo "The value of \"a\" is now $a" +echo "The value of \"a\" is now $a." echo diff --git a/LDP/guide/docbook/abs-guide/ex17.sh b/LDP/guide/docbook/abs-guide/ex17.sh index 9d560c50..e9974b01 100644 --- a/LDP/guide/docbook/abs-guide/ex17.sh +++ b/LDP/guide/docbook/abs-guide/ex17.sh @@ -2,6 +2,7 @@ # Call this script with at least 10 parameters, for example # ./scriptname 1 2 3 4 5 6 7 8 9 10 +MINPARAMS=10 echo @@ -29,11 +30,17 @@ fi # ... + if [ -n "${10}" ] # Parameters > $9 must be enclosed in {brackets}. then echo "Parameter #10 is ${10}" fi +if [ $# -lt "$MINPARAMS" ] +then + echo "Give me at least $MINPARAMS command-line arguments!" +fi + echo exit 0 diff --git a/LDP/guide/docbook/abs-guide/ex30.sh b/LDP/guide/docbook/abs-guide/ex30.sh index 8250031a..04e73804 100644 --- a/LDP/guide/docbook/abs-guide/ex30.sh +++ b/LDP/guide/docbook/abs-guide/ex30.sh @@ -30,8 +30,7 @@ case "$person" in echo "revans@zzy.net" echo "Business partner & old friend" ;; -# Note double semicolon to terminate -# each option. +# Note double semicolon to terminate each option. "J" | "j" ) echo diff --git a/LDP/guide/docbook/abs-guide/ex34.sh b/LDP/guide/docbook/abs-guide/ex34.sh index b1282894..4c8624f4 100644 --- a/LDP/guide/docbook/abs-guide/ex34.sh +++ b/LDP/guide/docbook/abs-guide/ex34.sh @@ -11,16 +11,20 @@ echo "Command-line argument #1 = $1" echo "Command-line argument #2 = $2" echo "Command-line argument #3 = $3" -echo set `uname -a` # Sets the positional parameters to the output # of the command `uname -a` +echo $_ # unknown +# Flags set in script. + echo "Positional parameters after set \`uname -a\` :" # $1, $2, $3, etc. reinitialized to result of `uname -a` echo "Field #1 of 'uname -a' = $1" echo "Field #2 of 'uname -a' = $2" echo "Field #3 of 'uname -a' = $3" +echo --- +echo $_ # --- echo exit 0 diff --git a/LDP/guide/docbook/abs-guide/ex40.sh b/LDP/guide/docbook/abs-guide/ex40.sh index c513db2e..47e7d00c 100644 --- a/LDP/guide/docbook/abs-guide/ex40.sh +++ b/LDP/guide/docbook/abs-guide/ex40.sh @@ -1,11 +1,13 @@ #!/bin/bash +# burn-cd.sh +# Script to automate burning a CDR. + SPEED=2 # May use higher speed if your hardware supports it. IMAGEFILE=cdimage.iso CONTENTSFILE=contents -DEFAULTDIR=/opt # Make sure this directory exists. - -# Script to automate burning a CDR. +DEFAULTDIR=/opt # This is the directory containing the data to be burned. + # Make sure it exists. # Uses Joerg Schilling's "cdrecord" package. # (http://www.fokus.gmd.de/nthp/employees/schilling/cdrecord.html) @@ -20,16 +22,19 @@ then else IMAGE_DIRECTORY=$1 fi - + +# Create a "table of contents" file. ls -lRF $IMAGE_DIRECTORY > $IMAGE_DIRECTORY/$CONTENTSFILE # The "l" option gives a "long" file listing. # The "R" option makes the listing recursive. # The "F" option marks the file types (directories get a trailing /). echo "Creating table of contents." +# Create an image file preparatory to burning it onto the CDR. mkisofs -r -o $IMAGFILE $IMAGE_DIRECTORY echo "Creating ISO9660 file system image ($IMAGEFILE)." +# Burn the CDR. cdrecord -v -isosize speed=$SPEED dev=0,0 $IMAGEFILE echo "Burning the disk." echo "Please be patient, this will take a while." diff --git a/LDP/guide/docbook/abs-guide/ex53.sh b/LDP/guide/docbook/abs-guide/ex53.sh index 1203e79c..8188a67b 100644 --- a/LDP/guide/docbook/abs-guide/ex53.sh +++ b/LDP/guide/docbook/abs-guide/ex53.sh @@ -1,11 +1,14 @@ #!/bin/bash +# Using "seq" + +echo for a in `seq 80` # or for a in $( seq 80 ) # Same as for a in 1 2 3 4 5 ... 80 (saves much typing!). # May also use 'jot' (if present on system). do echo -n "$a " -done +done # 1 2 3 4 5 ... 80 # Example of using the output of a command to generate # the [list] in a "for" loop. @@ -17,8 +20,34 @@ COUNT=80 # Yes, 'seq' may also take a replaceable parameter. for a in `seq $COUNT` # or for a in $( seq $COUNT ) do echo -n "$a " -done +done # 1 2 3 4 5 ... 80 -echo +echo; echo + +BEGIN=75 +END=80 + +for a in `seq $BEGIN $END` +# Giving "seq" two arguments starts the count at the first one, +#+ and continues until it reaches the second. +do + echo -n "$a " +done # 75 76 77 78 79 80 + +echo; echo + +BEGIN=45 +INTERVAL=5 +END=80 + +for a in `seq $BEGIN $INTERVAL $END` +# Giving "seq" three arguments starts the count at the first one, +#+ uses the second for a step interval, +#+ and continues until it reaches the third. +do + echo -n "$a " +done # 45 50 55 60 65 70 75 80 + +echo; echo exit 0 diff --git a/LDP/guide/docbook/abs-guide/ex55.sh b/LDP/guide/docbook/abs-guide/ex55.sh index 4d67c788..53d5281d 100644 --- a/LDP/guide/docbook/abs-guide/ex55.sh +++ b/LDP/guide/docbook/abs-guide/ex55.sh @@ -24,9 +24,9 @@ for i in /var/lock/subsys/*; do # --> Match variable name, which, in this case, is the file name. # --> This is the exact equivalent of subsys=`basename $i`. - # --> It gets it from the lock file name, and since if there - # --> is a lock file, that's proof the process has been running. - # --> See the "lockfile" entry, above. + # --> It gets it from the lock file name (if there is a lock file, + # -->+ that's proof the process has been running). + # --> See the "lockfile" entry, above. # Bring the subsystem down. @@ -34,7 +34,7 @@ for i in /var/lock/subsys/*; do /etc/rc.d/init.d/$subsys.init stop else /etc/rc.d/init.d/$subsys stop - # --> Suspend running jobs and daemons + # --> Suspend running jobs and daemons # --> using the 'stop' shell builtin. fi done diff --git a/LDP/guide/docbook/abs-guide/ex58.sh b/LDP/guide/docbook/abs-guide/ex58.sh index 205a8ff0..8cfd3746 100644 --- a/LDP/guide/docbook/abs-guide/ex58.sh +++ b/LDP/guide/docbook/abs-guide/ex58.sh @@ -3,17 +3,14 @@ # Backs up all files in current directory modified within last 24 hours #+ in a "tarball" (tarred and gzipped file). -NOARGS=0 -E_BADARGS=65 +BACKUPFILE=backup +archive=${1:-$BACKUPFILE} +# If no backup-archive filename specified on command line, +#+ it will default to "backup.tar.gz." -if [ $# = $NOARGS ] -then - echo "Usage: `basename $0` filename" - exit $E_BADARGS -fi - -tar cvf - `find . -mtime -1 -type f -print` > $1.tar -gzip $1.tar +tar cvf - `find . -mtime -1 -type f -print` > $archive.tar +gzip $archive.tar +echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"." # Stephane Chazelas points out that the above code will fail @@ -21,14 +18,14 @@ gzip $1.tar #+ or if any filenames contain blank characters. # He suggests the following alternatives: -# ------------------------------------------------------------- -# find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$1.tar" +# ------------------------------------------------------------------- +# find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar" # using the GNU version of "find". -# find . -mtime -1 -type f -exec tar rvf "$1.tar" '{}' \; -# portable to other UNIX flavors, but much slower. -# ------------------------------------------------------------- +# find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \; +# portable to other UNIX flavors, but much slower. +# ------------------------------------------------------------------- exit 0 diff --git a/LDP/guide/docbook/abs-guide/ex60.sh b/LDP/guide/docbook/abs-guide/ex60.sh index c6bc8ab8..d7e9d40d 100644 --- a/LDP/guide/docbook/abs-guide/ex60.sh +++ b/LDP/guide/docbook/abs-guide/ex60.sh @@ -1,13 +1,22 @@ #!/bin/bash +# Functions and parameters + +DEFAULT=default # Default param value. func2 () { - if [ -z "$1" ] # Checks if parameter #1 is zero length. + if [ -z "$1" ] # Is parameter #1 zero length? then - echo "-Parameter #1 is zero length.-" # Also if no parameter is passed. + echo "-Parameter #1 is zero length.-" # Or no parameter passed. else echo "-Param #1 is \"$1\".-" fi + variable=${1-$DEFAULT} # What does + echo "variable = $variable" #+ parameter substitution show? + # --------------------------- + # It distinguishes between + #+ no param and a null param. + if [ "$2" ] then echo "-Parameter #2 is \"$2\".-" diff --git a/LDP/guide/docbook/abs-guide/ex73.sh b/LDP/guide/docbook/abs-guide/ex73.sh index 4805380f..7e1a6b5c 100644 --- a/LDP/guide/docbook/abs-guide/ex73.sh +++ b/LDP/guide/docbook/abs-guide/ex73.sh @@ -18,12 +18,18 @@ then fi -if [ -n "$1" ] -then - blocks=$1 -else - blocks=$MINBLOCKS # Set to default of 40 blocks -fi # if nothing specified on command line. +blocks=${1:-$MINBLOCKS} # Set to default of 40 blocks, + #+ if nothing specified on command line. +# This is the equivalent of the command block below. +# -------------------------------------------------- +# if [ -n "$1" ] +# then +# blocks=$1 +# else +# blocks=$MINBLOCKS +# fi +# -------------------------------------------------- + if [ "$blocks" -lt $MINBLOCKS ] then diff --git a/LDP/guide/docbook/abs-guide/idelete.sh b/LDP/guide/docbook/abs-guide/idelete.sh index 94d789be..06391214 100644 --- a/LDP/guide/docbook/abs-guide/idelete.sh +++ b/LDP/guide/docbook/abs-guide/idelete.sh @@ -26,6 +26,7 @@ inum=`ls -i | grep "$1" | awk '{print $1}'` # Every file has an inode, a record that hold its physical address info. echo; echo -n "Are you absolutely sure you want to delete \"$1\" (y/n)? " +# The '-v' option to 'rm' also asks this. read answer case "$answer" in [nN]) echo "Changed your mind, huh?" diff --git a/LDP/guide/docbook/abs-guide/incompat.sh b/LDP/guide/docbook/abs-guide/incompat.sh index 239ab029..c56f104d 100644 --- a/LDP/guide/docbook/abs-guide/incompat.sh +++ b/LDP/guide/docbook/abs-guide/incompat.sh @@ -1,11 +1,8 @@ #!/bin/bash -# Erratic behavior of the "$*" and "$@" internal Bash variables, -# depending on whether these are quoted or not. -# Word splitting and linefeeds handled inconsistently. - -# This example script by Stephane Chazelas, -# and slightly modified by the document author. +# Erratic behavior of the "$*" and "$@" internal Bash variables, +#+ depending on whether they are quoted or not. +# Inconsistent handling of word splitting and linefeeds. set -- "First one" "second" "third:one" "" "Fifth: :one" @@ -135,3 +132,6 @@ echo # Try this script with ksh or zsh -y. exit 0 + +# This example script by Stephane Chazelas, +# and slightly modified by the document author. diff --git a/LDP/guide/docbook/abs-guide/int-or-string.sh b/LDP/guide/docbook/abs-guide/int-or-string.sh index 43480194..e8e26ab1 100644 --- a/LDP/guide/docbook/abs-guide/int-or-string.sh +++ b/LDP/guide/docbook/abs-guide/int-or-string.sh @@ -1,27 +1,45 @@ #!/bin/bash -# int-or-string.sh -# Integer or string? +# int-or-string.sh: Integer or string? a=2334 # Integer. let "a += 1" -echo "a = $a " # Integer, still. -echo +echo "a = $a " # a = 2335 +echo # Integer, still. -b=${a/23/BB} # Transform into a string. -echo "b = $b" # BB35 + +b=${a/23/BB} # Substitute "BB" for "23". + # This transforms $b into a string. +echo "b = $b" # b = BB35 declare -i b # Declaring it an integer doesn't help. -echo "b = $b" # BB35, still. +echo "b = $b" # b = BB35 let "b += 1" # BB35 + 1 = -echo "b = $b" # 1 +echo "b = $b" # b = 1 echo c=BB34 -echo "c = $c" # BB34 -d=${c/BB/23} # Transform into an integer. -echo "d = $d" # 2334 +echo "c = $c" # c = BB34 +d=${c/BB/23} # Substitute "23" for "BB". + # This makes $d an integer. +echo "d = $d" # d = 2334 let "d += 1" # 2334 + 1 = -echo "d = $d" # 2335 +echo "d = $d" # d = 2335 +echo + +# What about null variables? +e="" +echo "e = $e" # e = +let "e += 1" # Arithmetic operations allowed on a null variable? +echo "e = $e" # e = 1 +echo # Null variable transformed into an integer. + +# What about undeclared variables? +echo "f = $f" # f = +let "f += 1" # Arithmetic operations allowed? +echo "f = $f" # f = 1 +echo # Undeclared variable transformed into an integer. + + # Variables in Bash are essentially untyped. diff --git a/LDP/guide/docbook/abs-guide/isalpha.sh b/LDP/guide/docbook/abs-guide/isalpha.sh index ace17efe..38066a17 100644 --- a/LDP/guide/docbook/abs-guide/isalpha.sh +++ b/LDP/guide/docbook/abs-guide/isalpha.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Using "case" structure to filter a string. +# isalpha.sh: Using a "case" structure to filter a string. SUCCESS=0 FAILURE=-1 @@ -28,30 +28,78 @@ isalpha2 () # Tests whether *entire string* is alphabetic. esac } +isdigit () # Tests whether *entire string* is numerical. +{ # In other words, tests for integer variable. + [ $# -eq 1 ] || return $FAILURE + + case $1 in + *[!0-9]*|"") return $FAILURE;; + *) return $SUCCESS;; + esac +} -check_var () # Front-end to isalpha(). + +check_var () # Front-end to isalpha (). { if isalpha "$@" then - echo "$* = alpha" + echo "\"$*\" begins with an alpha character." + if isalpha2 "$@" + then # No point in testing if first char is non-alpha. + echo "\"$*\" contains only alpha characters." + else + echo "\"$*\" contains at least one non-alpha character." + fi else - echo "$* = non-alpha" # Also "non-alpha" if no argument passed. + echo "\"$*\" begins with a non-alpha character." + # Also "non-alpha" if no argument passed. fi + +echo + +} + +digit_check () # Front-end to isdigit (). +{ +if isdigit "$@" +then + echo "\"$*\" contains only digits [0 - 9]." +else + echo "\"$*\" has at least one non-digit character." +fi + +echo + } a=23skidoo b=H3llo c=-What? -d=`echo $b` # Command substitution. +d=What? +e=`echo $b` # Command substitution. +f=AbcDef +g=27234 +h=27a34 +i=27.34 check_var $a check_var $b check_var $c check_var $d +check_var $e +check_var $f check_var # No argument passed, so what happens? +# +digit_check $g +digit_check $h +digit_check $i -# Script improved by S.C. +exit 0 # Script improved by S.C. -exit 0 +# Exercise: +# -------- +# Write an 'isfloat ()' function that tests for floating point numbers. +# Hint: The function duplicates 'isdigit ()', +#+ but adds a test for a mandatory decimal point. diff --git a/LDP/guide/docbook/abs-guide/list-glob.sh b/LDP/guide/docbook/abs-guide/list-glob.sh index b756a392..81d324a7 100644 --- a/LDP/guide/docbook/abs-guide/list-glob.sh +++ b/LDP/guide/docbook/abs-guide/list-glob.sh @@ -6,7 +6,7 @@ echo for file in * do ls -l "$file" # Lists all files in $PWD (current directory). - # Recall that the wild card character "*" matches everything, + # Recall that the wild card character "*" matches every filename, # however, in "globbing", it doesn't match dot-files. # If the pattern matches no file, it is expanded to itself. diff --git a/LDP/guide/docbook/abs-guide/m4.sh b/LDP/guide/docbook/abs-guide/m4.sh index f7f1cb9d..ac8adcb5 100644 --- a/LDP/guide/docbook/abs-guide/m4.sh +++ b/LDP/guide/docbook/abs-guide/m4.sh @@ -5,7 +5,7 @@ string=abcdA01 echo "len($string)" | m4 # 7 echo "substr($string,4)" | m4 # A01 -echo "regexp($string,[0-1][0-1],\&Z)" | m4 # 01Z +echo "regexp($string,[0-1][0-1],\&Z)" | m4 # 01Z # Arithmetic echo "incr(22)" | m4 # 23 diff --git a/LDP/guide/docbook/abs-guide/mail-format.sh b/LDP/guide/docbook/abs-guide/mail-format.sh index 1e9c0189..1d816e3a 100644 --- a/LDP/guide/docbook/abs-guide/mail-format.sh +++ b/LDP/guide/docbook/abs-guide/mail-format.sh @@ -40,6 +40,6 @@ s/ *// #+ extolling a 164K Windows utility with similar functionality. # # An nice set of text processing utilities and an efficient -#+ scripting language makes unnecessary bloated executables. +#+ scripting language provide an alternative to bloated executables. exit 0 diff --git a/LDP/guide/docbook/abs-guide/manview.sh b/LDP/guide/docbook/abs-guide/manview.sh index c3cba3f8..a8cbcb82 100644 --- a/LDP/guide/docbook/abs-guide/manview.sh +++ b/LDP/guide/docbook/abs-guide/manview.sh @@ -1,14 +1,14 @@ #!/bin/bash # manview.sh: Formats the source of a man page for viewing. -# This is useful when writing man page source and you want to -# look at the intermediate results on the fly while working on it. +# This is useful when writing man page source and you want to +#+ look at the intermediate results on the fly while working on it. E_WRONGARGS=65 if [ -z "$1" ] then - echo "Usage: `basename $0` [filename]" + echo "Usage: `basename $0` filename" exit $E_WRONGARGS fi diff --git a/LDP/guide/docbook/abs-guide/numbers.sh b/LDP/guide/docbook/abs-guide/numbers.sh index ae1f625f..cca08082 100644 --- a/LDP/guide/docbook/abs-guide/numbers.sh +++ b/LDP/guide/docbook/abs-guide/numbers.sh @@ -1,24 +1,26 @@ #!/bin/bash -# numbers.sh: Representation of numbers. +# numbers.sh: Representation of numbers in different bases. -# Decimal +# Decimal: the default let "dec = 32" echo "decimal number = $dec" # 32 # Nothing out of the ordinary here. # Octal: numbers preceded by '0' (zero) -let "oct = 071" -echo "octal number = $oct" # 57 +let "oct = 032" +echo "octal number = $oct" # 26 # Expresses result in decimal. +# --------- ------ -- ------- # Hexadecimal: numbers preceded by '0x' or '0X' -let "hex = 0x7a" -echo "hexadecimal number = $hex" # 122 +let "hex = 0x32" +echo "hexadecimal number = $hex" # 50 # Expresses result in decimal. # Other bases: BASE#NUMBER # BASE between 2 and 64. +# NUMBER must use symbols within the BASE range, see below. let "bin = 2#111100111001101" echo "binary number = $bin" # 31181 @@ -38,13 +40,13 @@ echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA)) # 1295 170 44822 3375 -# Important note: +# Important note: +# -------------- # Using a digit out of range of the specified base notation #+ will give an error message. let "bad_oct = 081" # numbers.sh: let: oct = 081: value too great for base (error token is "081") -# Octal numbers use only digits in the range of 0 - 7. +# Octal numbers use only digits in the range 0 - 7. -exit 0 -# Thanks, Rich Bartell and Stephane Chazelas, for clarification. +exit 0 # Thanks, Rich Bartell and Stephane Chazelas, for clarification. diff --git a/LDP/guide/docbook/abs-guide/rot13.sh b/LDP/guide/docbook/abs-guide/rot13.sh index 505fa96c..c29cf651 100644 --- a/LDP/guide/docbook/abs-guide/rot13.sh +++ b/LDP/guide/docbook/abs-guide/rot13.sh @@ -1,12 +1,13 @@ #!/bin/bash -# rot13.sh: Classic rot13 algorithm, encryption that might fool a 3-year old. +# rot13.sh: Classic rot13 algorithm, +# encryption that might fool a 3-year old. # Usage: ./rot13.sh filename # or ./rot13.sh <filename # or ./rot13.sh and supply keyboard input (stdin) cat "$@" | tr 'a-zA-Z' 'n-za-mN-ZA-M' # "a" goes to "n", "b" to "o", etc. -# The 'cat "$@"' construction -# permits getting input either from stdin or from files. +# The 'cat "$@"' construction +#+ permits getting input either from stdin or from files. exit 0 diff --git a/LDP/guide/docbook/abs-guide/seconds.sh b/LDP/guide/docbook/abs-guide/seconds.sh index b8b6b2c5..afaeb5ad 100644 --- a/LDP/guide/docbook/abs-guide/seconds.sh +++ b/LDP/guide/docbook/abs-guide/seconds.sh @@ -1,13 +1,13 @@ #!/bin/bash -ENDLESS_LOOP=1 +TIME_LIMIT=10 INTERVAL=1 echo -echo "Hit Control-C to exit this script." +echo "Hit Control-C to exit before $TIME_LIMIT seconds." echo -while [ $ENDLESS_LOOP ] +while [ "$SECONDS" -le "$TIME_LIMIT" ] do if [ "$SECONDS" -eq 1 ] then @@ -17,8 +17,11 @@ do fi echo "This script has been running $SECONDS $units." + # On a slow or overburdened machine, the script may skip a count + #+ every once in a while. sleep $INTERVAL done +echo -e "\a" # Beep! exit 0 diff --git a/LDP/guide/docbook/abs-guide/self-destruct.sh b/LDP/guide/docbook/abs-guide/self-destruct.sh index 6895862f..5de8e4dd 100644 --- a/LDP/guide/docbook/abs-guide/self-destruct.sh +++ b/LDP/guide/docbook/abs-guide/self-destruct.sh @@ -8,3 +8,13 @@ echo "This line will not echo." # Instead, the shell sends a "Terminated" message to stdout. exit 0 + +# After this script terminates prematurely, +#+ what exit status does it return? +# +# sh self-destruct.sh +# echo $? +# 143 +# +# 143 = 128 + 15 +# TERM signal diff --git a/LDP/guide/docbook/abs-guide/stupid-script-tricks.sh b/LDP/guide/docbook/abs-guide/stupid-script-tricks.sh index b4755981..fcb5b3d0 100644 --- a/LDP/guide/docbook/abs-guide/stupid-script-tricks.sh +++ b/LDP/guide/docbook/abs-guide/stupid-script-tricks.sh @@ -1,5 +1,6 @@ #!/bin/bash # stupid-script-tricks.sh: Don't try this at home, folks. +# From "Stupid Script Tricks," Volume I. dangerous_variable=`cat /boot/vmlinuz` # The compressed Linux kernel itself. diff --git a/LDP/guide/docbook/abs-guide/symlinks.sh b/LDP/guide/docbook/abs-guide/symlinks.sh index 5d93084b..09331592 100644 --- a/LDP/guide/docbook/abs-guide/symlinks.sh +++ b/LDP/guide/docbook/abs-guide/symlinks.sh @@ -1,14 +1,21 @@ #!/bin/bash # symlinks.sh: Lists symbolic links in a directory. -ARGS=1 # Expect one command-line argument. -if [ $# -ne "$ARGS" ] # If not 1 arg... -then - directory=`pwd` # current working directory -else - directory=$1 -fi +directory=${1-`pwd`} +# Defaults to current working directory, +#+ if not otherwise specified. +# Equivalent to code block below. +# ---------------------------------------------------------- +# ARGS=1 # Expect one command-line argument. +# +# if [ $# -ne "$ARGS" ] # If not 1 arg... +# then +# directory=`pwd` # current working directory +# else +# directory=$1 +# fi +# ---------------------------------------------------------- echo "symbolic links in directory \"$directory\"" diff --git a/LDP/guide/docbook/abs-guide/symlinks2.sh b/LDP/guide/docbook/abs-guide/symlinks2.sh index 7572581c..d889779f 100644 --- a/LDP/guide/docbook/abs-guide/symlinks2.sh +++ b/LDP/guide/docbook/abs-guide/symlinks2.sh @@ -1,22 +1,20 @@ #!/bin/bash # symlinks.sh: Lists symbolic links in a directory. -ARGS=1 # Expect one command-line argument. -OUTFILE=symlinks.list # save file +OUTFILE=symlinks.list # save file -if [ $# -ne "$ARGS" ] # If not 1 arg... -then - directory=`pwd` # current working directory -else - directory=$1 -fi +directory=${1-`pwd`} +# Defaults to current working directory, +#+ if not otherwise specified. -echo "symbolic links in directory \"$directory\"" -for file in "$( find $directory -type l )" # -type l = symbolic links +echo "symbolic links in directory \"$directory\"" > "$OUTFILE" +echo "---------------------------" >> "$OUTFILE" + +for file in "$( find $directory -type l )" # -type l = symbolic links do echo "$file" -done | sort > "$OUTFILE" # stdout of loop -# ^^^^^^^^^^^^ redirected to save file. +done | sort >> "$OUTFILE" # stdout of loop +# ^^^^^^^^^^^^^ redirected to save file. exit 0