diff --git a/LDP/guide/docbook/abs-guide/Change.log b/LDP/guide/docbook/abs-guide/Change.log index 238cfec5..3e9f5ffb 100644 --- a/LDP/guide/docbook/abs-guide/Change.log +++ b/LDP/guide/docbook/abs-guide/Change.log @@ -6,6 +6,120 @@ http://personal.riverusers.com/~thegrendel/Change.log ------------------------------------------------------------------------ +Version 3.2 +Blueberry release, 02/06/05 + +1) In the "Starting Off With a Sha-Bang" chapter: + Fixed small typo (if [ $# -ne $Number_of_expected args ]). + Thanks, Robbie Morrison. + Added epigraph to "Why Shell Programming?" section. + +2) In "Special Characters" chapter: + At "&" entry, added comment about Nasimuddin Ansari's suggested change + to "background-loop.sh" example. + +3) In "Colorizing Scripts" section of "Miscellany" chapter: + Added link to Henry/teikedvl's utility for creating colorized scripts. + +4) In "Complex Functions and Function Complexities" chapter: + Added "func-cmdlinearg.sh" example script to clear up confusion + about command-line args passed to a script. + +5) In "Local Variables" section of "Functions" chapter: + Fixed typo in example in footnote. + (Thank you, jaka kranjc.) + +6) In "File and Archiving Commands" section of "External Commands" Chapter: + At "files" entry, added example of finding specific file types + in a given directory. + +7) In "Communications Commands" section of "External Commands" chapter: + At "ssh" entry, added caution about ssh using up loop's stdin. + (Thanks, Jason Bechtel.) + +8) In "Special Variable Types" section of "Introduction to Variables" chapter + Some fixups for "ex18.sh" example. + Added Chris Monson's example of finding last command line parameter. + +9) In "Parameter Substitution" section of "Variables Revisited" chapter: + Added material to "param-sub.sh" example. + +10) In "Double Parentheses Construct" section of "Variables Revisited" + chapter: + In "c-vars.sh" example, added instances of differing side-effects + of pre- and post-increment operators. + (Thanks, Jeroen Domburg.) + +11) In "Indirect References to Variables" section of "Variables Revisited" + chapter: + Added Nils Radtke's example of building dynamic variable names. + +12) In "Text Processing" section of "External Commands" Chapter: + Added extra explanatory lines at "grep" listing. + Moved "manview.sh" script example from Contributed Script appendix + to "groff, tbl, eqn" entry. + +13) In the "Shell Wrappers" section of "Miscellany" chapter: + Added redirection comment to "ex3.sh" example. + (Thanks, jaka kranjc.) + +14) In "Regular Expressions" chapter: + Added listing of components of REs. + Streamlined the discussion following. + +15) In "$RANDOM" section of "Variables Revisited" chapter: + Added footnote about randomness and pseudorandomness. + Added a couple of cross-links in the text. + +16) In "System and Administrative Commands" chapter: + Added usage example at "last" entry. + +17) In "/dev" section of "/dev and /proc" chapter: + Changed reference URL from slashdot.org to net.cn (a known spam ISP). + Added to footnote about mounting a USB flash drive. + +18) In "Gotchas" chapter: + Added note about not hyphenating function names. + +19) In "Bibliography" section: + Added William Parks' Dec. '04 "Linux Gazette" article to his listing. + Added entry for "Unix Oneliners." + Added "http://www.zazzybob.com" entry. + +20) In "Writing Scripts" section of "Exercises" appendix: + In "Intermediate" section, added "Integer or String" exercise . + In "Intermediate" section, added "Logged in User Information" + exercise . + +21) In "Contributed Scripts" appendix: + Added "cdll" expanded 'cd' command. + (Thanks, Phil Braham.) + Added "wgetter2.bash" example script. + (Thanks, Little Monster .) + +22) In "Localization" appendix: + Again, fixed quoting problem in "localized.sh" in-line example + (per Bruno Haible). + +23) In "Important System Directories" appendix: + Corrected "/sys" entry. + Added "/mnt," "/dev," "/proc," and "/media" entries. + +24) In "Analyzing Scripts" section of "Exercises" appendix: + Added short example script. + +25) Added comment block to sample .bashrc file (Appendix G). + (Thanks, Ane-Pieter Wieringa.) + +26) Deleted unwanted space in ": < + + @@ -311,6 +313,7 @@ Uncomment line below to generate index. + ]> @@ -329,19 +332,12 @@ Uncomment line below to generate index. - 3.1 - 14 November 2004 + 3.2 + 06 February 2005 - - 2.8 - 11 July 2004 - mc - 'ELDERBERRY' release: Minor update. - - 3.0 03 Oct 2004 @@ -356,6 +352,13 @@ Uncomment line below to generate index. 'BAYBERRY' release: Bugfix update. + + 3.2 + 06 Feb 2005 + mc + 'BLUEBERRY' release: Minor update. + + @@ -376,7 +379,7 @@ Uncomment line below to generate index. introduction to programming concepts. + url="http://personal.riverusers.com/~thegrendel/abs-guide-3.2.tar.bz2"> The latest update of this document, as an archived, bzip2-ed tarball including both the SGML source and rendered HTML, may @@ -419,6 +422,13 @@ Uncomment line below to generate index. Why Shell Programming? + + + Herbert Mayer + No programming language is perfect. There is not even a single + best language; there are only languages well suited or perhaps poorly + suited for particular purposes. + A working knowledge of shell scripting is essential to anyone @@ -737,7 +747,7 @@ exit $WHATEVER # Doesn't matter. The script will not exit here. - if [ $# -ne $Number_of_expected args ] + if [ $# -ne $Number_of_expected_args ] then echo "Usage: `basename $0` script_parameters" exit $E_WRONG_ARGS @@ -3133,7 +3143,11 @@ arch=$(uname -m) linkend="varrefnew">indirect referencing. args=$# # Number of args passed. -lastarg=${!args} # Note that lastarg=${!$#} doesn't work. +lastarg=${!args} +# Or: lastarg=${!#} +# (Thanks, Chris Monson.) +# Note that lastarg=${!$#} doesn't work. + Some scripts can perform different operations, @@ -8057,6 +8071,33 @@ echo "n = $n" # n = 2 &indref; + + + Nils Radtke shows how to build dynamic + variable names and evaluate their contents. This can be useful + when sourcing configuration files. + + #!/bin/bash + + +# --------------------------------------------- +# This could be "sourced" from a separate file. +isdnMyProviderRemoteNet=172.16.0.100 +isdnYourProviderRemoteNet=10.0.0.10 +isdnOnlineService="MyProvider" +# --------------------------------------------- + + +remoteNet=$(eval "echo \$$(echo isdn${isdnOnlineService}RemoteNet)") +remoteNet=$(eval "echo \$$(echo isdnMyProviderRemoteNet)") +remoteNet=$(eval "echo \$isdnMyProviderRemoteNet") +remoteNet=$(eval "echo $isdnMyProviderRemoteNet") + +echo "$remoteNet" # 172.16.0.100 + + + + Passing an indirect reference to <replaceable>awk</replaceable> &coltotaler2; @@ -8084,10 +8125,21 @@ echo "n = $n" # n = 2 $RANDOM $RANDOM: generate random integer - $RANDOM is an internal Bash function (not a constant) that - returns a pseudorandom integer in the range - 0 - 32767. $RANDOM should not be used - to generate an encryption key. + $RANDOM is an internal Bash function (not a constant) that + returns a pseudorandom + + True randomness, insofar as + it exists at all, is only to be found in certain + incompletely understood natural phenomena such as + radioactive decay. Computers can only simulate + randomness, and computer-generated sequences of + random numbers are therefore referred to as + pseudorandom. + + integer in the range 0 - 32767. $RANDOM should + not be used to generate an encryption + key. Generating random numbers @@ -8164,10 +8216,10 @@ rnumber=$(((RANDOM%30/3+1)*3)) pseudorandom numbers than the $RANDOM variable. dd if=/dev/urandom of=targetfile bs=1 count=XX creates a file of well-scattered - pseudorandom numbers. However, assigning these numbers - to a variable in a script requires a workaround, such as - filtering through od (as in - above example) or using dd + pseudorandom numbers. However, assigning these numbers to a + variable in a script requires a workaround, such as filtering + through od (as in above example and + ) or using dd (see ). @@ -11136,16 +11188,17 @@ find "$DIR" -type f -atime +5 -exec rm {} \; find /etc -exec grep '[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*' {} \; # Finds all IP addresses (xxx.xxx.xxx.xxx) in /etc directory files. -# There a few extraneous hits - how can they be filtered out? +# There a few extraneous hits. How can they be filtered out? # Perhaps by: find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ - | grep '^[^.][^.]*\.[^.][^.]*\.[^.][^.]*\.[^.][^.]*$' -# [:digit:] is one of the character classes -# introduced with the POSIX 1003.2 standard. +| grep '^[^.][^.]*\.[^.][^.]*\.[^.][^.]*\.[^.][^.]*$' +# +# [:digit:] is one of the character classes +#+ introduced with the POSIX 1003.2 standard. -# Thanks, S.C. +# Thanks, Stephane Chazelas. @@ -12216,18 +12269,20 @@ fi &grp; - How can grep search for two separate - patterns? What if you want grep to display - all lines in a file or files that contain - both pattern1 and - pattern2? + How can grep search for two (or + more) separate patterns? What if you want + grep to display all lines in a file + or files that contain both pattern1 + and pattern2? - One method of accomplishing this is to One method is to pipe the result of grep pattern1 to grep pattern2. + For example, given the following file: + - # tstfile + # Filename: tstfile This is a sample file. This is an ordinary text file. @@ -12236,8 +12291,12 @@ This file is not unusual. Here is some text. + Now, let's search this file for lines containing + both file and + test . . . + bash$ grep file tstfile -# tstfile +# Filename: tstfile This is a sample file. This is an ordinary text file. This file does not contain any unusual text. @@ -12247,6 +12306,8 @@ Here is some text. This is an ordinary text file. This file does not contain any unusual text. + -- + egrep (extended grep) is the same @@ -12258,7 +12319,7 @@ Here is some text. fgrep (fast grep) is the same as grep -F. It does a literal string search (no regular - expressions), which allegedly speeds things up a bit. + expressions), which usually speeds things up a bit. agrep (approximate grep) extends the capabilities of @@ -12845,7 +12906,7 @@ tr -d 0-9 <filename is groff. This is the enhanced GNU version of the venerable UNIX roff/troff display and typesetting package. Manpages - use groff (see ). + use groff. The tbl table processing utility is considered part of groff, as its @@ -12857,9 +12918,16 @@ tr -d 0-9 <filename its function is to convert equation markup into groff commands. + + <command>manview</command>: Viewing formatted manpages + + &manview; + + + lex yacc @@ -13368,6 +13436,24 @@ tr -d 0-9 <filename + + # Find sh and Bash scripts in a given directory: + +DIRECTORY=/usrlocal/bin +KEYWORD=Bourne +# Bourne and Bourne-Again shell scripts + +file $DIRECTORY/* | fgrep $KEYWORD + +# Output: + +# /usr/local/bin/burn-cd: Bourne-Again shell script text executable +# /usr/local/bin/burnit: Bourne-Again shell script text executable +# /usr/local/bin/cassette.sh: Bourne shell script text executable +# /usr/local/bin/copy-cd: Bourne-Again shell script text executable +# . . . + + Stripping comments from C program files &stripc; @@ -14675,7 +14761,7 @@ echo "tempfile name = $tempfile" - wget + wget wget @@ -14697,6 +14783,8 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE "efetch; + See also . + @@ -14793,6 +14881,18 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE &remote; + + Within a loop, ssh may cause + unexpected behavior. According to a + Usenet post in the comp.unix shell archives, + ssh inherits the loop's + stdin. To remedy this, pass + ssh either the + or option. + Thanks, Jason Bechtel, for pointing this out. + + @@ -16316,9 +16416,23 @@ sudo cp /root/secretfile /home/bozo/secret logged in + List last logged in users, as read from /var/log/wtmp. This command can also show remote logins. + + For example, to show the last few times the system + rebooted: + + bash$ last reboot +reboot system boot 2.6.9-1.667 Fri Feb 4 18:18 (00:02) + reboot system boot 2.6.9-1.667 Fri Feb 4 15:20 (01:27) + reboot system boot 2.6.9-1.667 Fri Feb 4 12:56 (00:49) + reboot system boot 2.6.9-1.667 Thu Feb 3 21:08 (02:17) + . . . + + wtmp begins Tue Feb 1 12:50:09 2005 + @@ -16729,7 +16843,7 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< - lastlog + lastlog lastlog @@ -17655,7 +17769,8 @@ Average: all 6.33 1.70 14.71 0.00 77.26ifconfig - Network interface configuration and tuning utility. + Network interface configuration + and tuning utility. bash$ ifconfig -a lo Link encap:Local Loopback @@ -19972,19 +20087,41 @@ echo "This line had better not echo." # Follows an 'exit' command.A Brief Introduction to Regular Expressions An expression is a string of characters. Those characters - that have an interpretation above and beyond their literal + having an interpretation above and beyond their literal meaning are called metacharacters. A quote symbol, for example, may denote speech by a person, ditto, or a meta-meaning for the symbols that follow. Regular Expressions are sets of characters and/or - metacharacters that an operating system endows with special - features. + metacharacters that match (or specify) patterns. + + A Regular Expression contains one or more of the + following: - The simplest type of Regular Expression is a - character string that retains its literal meaning, not - containing any metacharacters. + + + + A character set. These are the characters retaining their + literal meaning. The simplest type of Regular Expression + consists only of a character set, with no + metacharacters. + + + + An anchor. These designate (anchor) + the position in the line of text that the RE is to + match. For example, ^, and $ + are anchors. + + + + Modifiers. These expand or narrow + (modify) the range of text the RE is + to match. Modifiers include the asterisk, brackets, and + the backslash. + + + - The main uses for Regular Expressions (REs) are text searches and string manipulation. An RE @@ -20091,9 +20228,6 @@ exit 0 The dollar sign -- $ -- at the end of an RE matches the end of a line. ^$ matches blank lines. - The ^ and $ are known as - anchors, since they indicate or anchor a - position within an RE. @@ -20244,9 +20378,10 @@ This line contains no numbers at all. # No match. <anchor id="extregex">Extended REs - Used in egrep, + Additional metacharacters added to the basic set. Used + in egrep, awk, and Perl + linkend="perlref">Perl. @@ -21320,6 +21455,15 @@ exit # Invokes "exit ()" function, not "exit" builtin. command works on arguments passed to functions (see ). + But, what about command-line arguments passed to the script? + Does a function see them? Well, let's clear up the confusion. + + + Functions and command-line args passed to the script + &funccmdlinearg; + + + In contrast to certain other programming languages, shell scripts normally pass only value parameters to functions. Variable names (which are actually pointers), if @@ -21649,7 +21793,7 @@ echo "global_var = $global_var" # global_var = 37 recursive_function () { -(( $1 < $2 )) && f $(( $1 + 1 )) $2; +(( $1 < $2 )) && recursive_function $(( $1 + 1 )) $2; # As long as 1st parameter is less than 2nd, #+ increment 1st and recurse. } @@ -22376,6 +22520,8 @@ exit 0 then, as root, mkdir /mnt/flashdrive. To actually mount the drive, use the following command: mount /mnt/flashdrive + Newer Linux distros automount flash drives in the + /media directory. /dev/sda1 /mnt/flashdrive auto noauto,user,noatime 0 0 @@ -22406,7 +22552,7 @@ exit 0 [Mark contributed the above example.] Downloading a URL: - bash$ exec 5<>/dev/tcp/www.slashdot.org/80 + bash$ exec 5<>/dev/tcp/www.net.cn/80 bash$ echo -e "GET / HTTP/1.0\n" >&5 bash$ cat <&5 @@ -23199,9 +23345,13 @@ echo $_ # $_ is a special variable set to last arg of last command. xyz((!*=value2 # Causes severe problems. - Using a hyphen or other reserved characters in a variable name. + Using a hyphen or other reserved characters in a variable name (or + function name). var-1=23 -# Use 'var_1' instead. +# Use 'var_1' instead. + +function-whatever () +# Use 'function_whatever ()' instead. Using the same name for a variable and a function. This can make a @@ -23499,8 +23649,10 @@ find $HOME -type f -atime +30 -size 100k | { # The "error.log" file will not have anything written to it. + -- + Using suid commands within scripts is risky, as it may compromise system security. Setting the suid permission on @@ -24207,6 +24359,9 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" # Greater ASCI substitutes a clean and logical syntax for the clumsy constructs just discussed. + Henry/teikedvl has likewise created a utility (http://scriptechocolor.sourceforge.net/) to simplify creation of colorized scripts. + @@ -25093,14 +25248,15 @@ fi professor. Crazy as a loon, the fellow was. At the sight of a book, any book -- at the library, at a bookstore, anywhere -- he would become totally obsessed with the idea that he could have - written it, should have written it, and done a better job of it to - boot. He would thereupon rush home and proceed to do just that, + written it, should have written it -- and done a better job of it + to boot. He would thereupon rush home and proceed to do just that, write a book with the very same title. When he died some years later, he allegedly had several thousand books to his credit, probably putting even Asimov to shame. The books might not have been any good -- who knows -- but does that really matter? Here's a fellow who lived his dream, even if he was obsessed by it, - driven by it, and I can't help admiring the old coot... + driven by it . . . and somehow I can't help admiring the old + coot. @@ -25129,7 +25285,7 @@ fi mortgage calculator, the judge Scrabble® adjudicator, and the yawl + url="http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz">yawl word gaming list package. He got his start in programming using FORTRAN IV on a CDC 3800, but is not the least bit nostalgic for those days. @@ -25308,22 +25464,23 @@ fi Others contributing scripts, making helpful suggestions, and pointing out errors were Gabor Kiss, Leopold Toetsch, Peter Tillier, Marcus Berglof, Tony Richardson, Nick Drage (script - ideas!), Rich Bartell, Jess Thrysoee, Adam Lazur, Bram Moolenaar, - Baris Cicek, Greg Keraunen, Keith Matthews, Sandro Magi, Albert - Reiner, Dim Segebart, Rory Winston, Lee Bigelow, Wayne Pollock, - jipe, Mark, bojster, - Ender, Emilio Conti, Ian. D. Allen, Arun - Giridhar, Dennis Leeuw, Dan Jacobson, Aurelio Marinho Jargas, - Edward Scholtz, Jean Helou, Chris Martin, Lee Maschmeyer, - Bruno Haible, Wilbert Berendsen, Sebastien Godard, Bjön - Eriksson, nyal, John MacDonald, Joshua Tschida, - Troy Engel, Manfred Schwarb, Amit Singh, Bill Gradwohl, David - Lombard, Jason Parker, Steve Parker, Bruce W. Clare, William - Park, Vernia Damiano, Mihai Maties, Jeremy Impson, Ken Fuchs, - Frank Wang, Sylvain Fourmanoit, Matthew Walker, Kenny Stauffer, - Filip Moritz, Andrzej Stefanski, Daniel Albers, Stefano Palmeri, - Alfredo Pironti, and David Lawyer (himself an author of four - HOWTOs). + ideas!), Rich Bartell, Jess Thrysoee, Adam Lazur, Bram + Moolenaar, Baris Cicek, Greg Keraunen, Keith Matthews, Sandro + Magi, Albert Reiner, Dim Segebart, Rory Winston, Lee Bigelow, + Wayne Pollock, jipe, Mark, + bojster, Ender, Emilio Conti, + Ian. D. Allen, Arun Giridhar, Dennis Leeuw, Dan Jacobson, Aurelio + Marinho Jargas, Edward Scholtz, Jean Helou, Chris Martin, Lee + Maschmeyer, Bruno Haible, Wilbert Berendsen, Sebastien Godard, + Bjön Eriksson, nyal, John MacDonald, Joshua + Tschida, Troy Engel, Manfred Schwarb, Amit Singh, Bill Gradwohl, + David Lombard, Jason Parker, Steve Parker, Bruce W. Clare, + William Park, Vernia Damiano, Mihai Maties, Jeremy Impson, + Ken Fuchs, Frank Wang, Sylvain Fourmanoit, Matthew Walker, + Kenny Stauffer, Filip Moritz, Andrzej Stefanski, Daniel Albers, + Stefano Palmeri, Nils Radtke, Jeroen Domburg, Alfredo Pironti, + Phil Braham, Little Monster (Alexis), and David + Lawyer (himself an author of four HOWTOs). My gratitude to Chet Ramey and Brian Fox for writing Bash, @@ -25858,6 +26015,13 @@ fi + + + Example shell scripts at zazzybob. + + + Steve Parker's + + + Mini-scripts at Unix + Oneliners. + + + Giles Orr's url="http://linuxgazette.net/108/park.html">article in the November, 2004 issue of the Linux Gazette on - adding string functions to Bash. + adding string functions to Bash, with a followup article + in the December issue, and yet another in + the January, 2005 issue. @@ -26063,12 +26239,6 @@ fi illustrate some interesting shell programming techniques. They are useful, too. Have fun analyzing and running them. - - <command>manview</command>: Viewing formatted manpages - - &manview; - - <command>mailformat</command>: Formatting an e-mail message &mailformat; @@ -26254,13 +26424,21 @@ fi - This powerful script helps hunt down spammers . + This powerful script helps hunt down spammers. Spammer Identification &isspammer2; + Little Monster's front end to wget. + + + Making <command>wget</command> easier to use + &wgetter2; + + To end this section, a review of the basics . . . and more. @@ -26268,6 +26446,11 @@ fi &basicsreviewed; + + An expanded <command>cd</command> command + &cdll; + + @@ -27731,7 +27914,6 @@ exit 0 and utilities (such as fsck). - /usr/sbin More system administrative programs and utilities. @@ -27760,15 +27942,40 @@ exit 0 - /tmp - System temporary files. + /dev + Device directory. Entries (but not + mount points) for physical and virtual devices. + See . + + + + /proc + Process directory. Contains information and statistics + about running processes and kernel parameters. + See . /sys - Systemwide process directory. Contains information and - statistics about running processes. This is newly added to Linux - with the 2.6.X kernels. + Systemwide device directory. Contains information and + statistics about device and device names. This is newly + added to Linux with the 2.6.X kernels. + + + + /mnt + Mount. Directory for mounting + hard drive partitions, such as /mnt/dos, and physical + devices. In newer Linux distros, the /media directory has taken + over as the preferred mount point for I/O devices. + + + + /media + In newer Linux distros, the preferred mount point for + I/O devices, such as CD ROMs or USB flash drives. @@ -27799,6 +28006,11 @@ exit 0 More systemwide library files. + + /tmp + System temporary files. + + /boot System boot directory. The kernel, @@ -27845,9 +28057,13 @@ error() exit $E_CDERROR } -cd $var || error "`eval_gettext \"Can\'t cd to \$var.\"`" +cd $var || error "`eval_gettext \"Can\'t cd to \\\$var.\"`" +# The triple backslashes (escapes) in front of $var needed +#+ "because eval_gettext expects a string +#+ where the variable values have not yet been substituted." +# -- per Bruno Haible read -p "`gettext \"Enter the value: \"`" var -# ... +# ... # ------------------------------------------------------------------ @@ -28593,6 +28809,23 @@ exit 0 --- + Explain what the following script does. It is really just + a parameterized command-line pipe. + + + #!/bin/bash + +DIRNAME=/usr/bin +FILETYPE="shell script" +LOGFILE=logfile + +file "$DIRNAME"/* | fgrep "$FILETYPE" | tee $LOGFILE | wc -l + +exit 0 + + + --- + A reader sent in the following code snippet. while read LINE @@ -28638,7 +28871,7 @@ done < `tail -f /var/log/messages` - <anchor id="exeasy1">Easy + <anchor id="exeasy1">EASY Home Directory Listing @@ -28766,7 +28999,21 @@ done < `tail -f /var/log/messages` - <anchor id="exmedium1">Intermediate + <anchor id="exmedium1">INTERMEDIATE + + + Integer or String + + Write a script function + that determines if an argument passed to it is an integer + or a string. The function will return TRUE (0) if + passed an integer, and FALSE (1) if passed a string. + Hint: What does the following expression return + when $1 is not an + integer? + expr $1 + 0 + + Managing Disk Space @@ -28780,6 +29027,20 @@ done < `tail -f /var/log/messages` + + Logged in User Information + + + For all logged in users, show their real names and the time + and date of their last login. + + Hint: use who, + lastlog, + and parse /etc/passwd. + + + + Safe Delete @@ -28929,7 +29190,7 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 - <anchor id="exdifficult1">Difficult + <anchor id="exdifficult1">DIFFICULT Testing Passwords @@ -29549,6 +29810,11 @@ fairly detailed rundown on the Playfair Cipher and its solution methods.14 Nov 2004 BAYBERRY release: Bugfix update. + + + 06 Feb 2005 + BLUEBERRY release: Minor update. + diff --git a/LDP/guide/docbook/abs-guide/background-loop.sh b/LDP/guide/docbook/abs-guide/background-loop.sh index 66ad5515..35afcdaf 100644 --- a/LDP/guide/docbook/abs-guide/background-loop.sh +++ b/LDP/guide/docbook/abs-guide/background-loop.sh @@ -36,3 +36,7 @@ echo # This 'echo' sometimes will not display. # The foreground loop preempts the background one. exit 0 + +# Nasimuddin Ansari suggests adding sleep 1 +#+ after the echo -n "$i" in lines 6 and 14, +#+ for some real fun. diff --git a/LDP/guide/docbook/abs-guide/bashrc b/LDP/guide/docbook/abs-guide/bashrc index 662bf00c..9aae5af0 100644 --- a/LDP/guide/docbook/abs-guide/bashrc +++ b/LDP/guide/docbook/abs-guide/bashrc @@ -42,8 +42,13 @@ function get_xserver () { case $TERM in xterm ) - XSERVER=$(who am i | awk '{print $NF}' | tr -d ')''(' ) - XSERVER=${XSERVER%%:*} + XSERVER=$(who am i | awk '{print $NF}' | tr -d ')''(' ) + # Ane-Pieter Wieringa suggests the following alternative: + # I_AM=$(who am i) + # SERVER=${I_AM#*(} + # SERVER=${SERVER%*)} + + XSERVER=${XSERVER%%:*} ;; aterm | rxvt) # find some code that works here..... diff --git a/LDP/guide/docbook/abs-guide/c-vars.sh b/LDP/guide/docbook/abs-guide/c-vars.sh index 09155daa..4ede7251 100644 --- a/LDP/guide/docbook/abs-guide/c-vars.sh +++ b/LDP/guide/docbook/abs-guide/c-vars.sh @@ -22,6 +22,18 @@ echo "a (after --a) = $a" echo +######################################################## +# Note that, as in C, pre- and post-decrement operators +#+ have slightly different side-effects. + +n=1; let --n && echo "True" || echo "False" # False +n=1; let n-- && echo "True" || echo "False" # True + +# Thanks, Jeroen Domburg. +######################################################## + +echo + (( t = a<45?7:11 )) # C-style trinary operator. echo "If a < 45, then t = 7, else t = 11." echo "t = $t " # Yes! diff --git a/LDP/guide/docbook/abs-guide/commentblock.sh b/LDP/guide/docbook/abs-guide/commentblock.sh index 1ba4c5d3..c2a98f4e 100644 --- a/LDP/guide/docbook/abs-guide/commentblock.sh +++ b/LDP/guide/docbook/abs-guide/commentblock.sh @@ -1,7 +1,7 @@ #!/bin/bash # commentblock.sh -: << COMMENTBLOCK +: <<COMMENTBLOCK echo "This line will not echo." This is a comment line missing the "#" prefix. This is another comment line missing the "#" prefix. @@ -20,7 +20,7 @@ echo "Exit value of above \"COMMENTBLOCK\" is $?." # 0 # This saves having to put a "#" at the beginning of each line, #+ then having to go back and delete each "#" later. -: << DEBUGXXX +: <<DEBUGXXX for file in * do cat "$file" diff --git a/LDP/guide/docbook/abs-guide/cvt.sh b/LDP/guide/docbook/abs-guide/cvt.sh index fa7bf615..ce4cedf1 100644 --- a/LDP/guide/docbook/abs-guide/cvt.sh +++ b/LDP/guide/docbook/abs-guide/cvt.sh @@ -17,7 +17,7 @@ else fi # Assumes all files in the target directory are MacPaint image files, -# + with a ".mac" suffix. +#+ with a ".mac" filename suffix. for file in $directory/* # Filename globbing. do diff --git a/LDP/guide/docbook/abs-guide/dev-tcp.sh b/LDP/guide/docbook/abs-guide/dev-tcp.sh index 998ac0df..2377fe2c 100644 --- a/LDP/guide/docbook/abs-guide/dev-tcp.sh +++ b/LDP/guide/docbook/abs-guide/dev-tcp.sh @@ -4,14 +4,14 @@ # Script by Troy Engel. # Used with permission. -TCP_HOST=www.slashdot.org -TCP_PORT=80 # Port 80 is http. +TCP_HOST=www.dns-diy.com # A known spam-friendly ISP. +TCP_PORT=80 # Port 80 is http. -# Try to connect. (Somewhat similar to a 'ping.') +# Try to connect. (Somewhat similar to a 'ping' . . .) echo "HEAD / HTTP/1.0" >/dev/tcp/${TCP_HOST}/${TCP_PORT} MYEXIT=$? -: << EXPLANATION +: <<EXPLANATION If bash was compiled with --enable-net-redirections, it has the capability of using a special character device for both TCP and UDP redirections. These redirections are used identically as STDIN/STDOUT/STDERR. The device entries diff --git a/LDP/guide/docbook/abs-guide/directory-info.sh b/LDP/guide/docbook/abs-guide/directory-info.sh index 171c1e68..2748fdba 100644 --- a/LDP/guide/docbook/abs-guide/directory-info.sh +++ b/LDP/guide/docbook/abs-guide/directory-info.sh @@ -33,7 +33,7 @@ declare -a \ # Here document used as a comment block. -: << LSfieldsDoc +: <<LSfieldsDoc # # # # # List Filesystem Directory Information # # # # # # # ListDirectory "FileGlob" "Field-Array-Name" @@ -163,7 +163,7 @@ IsNumber() # IndexList -if -of Field-Array-Filename Index-Array-Filename # # # # # -: << IndexListDoc +: <<IndexListDoc Walk an array of directory fields produced by ListDirectory Having suppressed the line breaks in an otherwise line oriented diff --git a/LDP/guide/docbook/abs-guide/ex10.sh b/LDP/guide/docbook/abs-guide/ex10.sh index 563a45d6..dd57b9bd 100644 --- a/LDP/guide/docbook/abs-guide/ex10.sh +++ b/LDP/guide/docbook/abs-guide/ex10.sh @@ -1,5 +1,9 @@ #!/bin/bash +# Tip: +# If you're unsure of how a certain condition would evaluate, +#+ test it in an if-test. + echo echo "Testing \"0\"" @@ -109,6 +113,7 @@ else fi # "$false" is false. # Now, we get the expected result. +# What would happen if we tested the uninitialized variable "$true"? echo diff --git a/LDP/guide/docbook/abs-guide/ex18.sh b/LDP/guide/docbook/abs-guide/ex18.sh index cfd9c328..51e3d01b 100644 --- a/LDP/guide/docbook/abs-guide/ex18.sh +++ b/LDP/guide/docbook/abs-guide/ex18.sh @@ -1,4 +1,5 @@ #!/bin/bash +# ex18.sh # Does a 'whois domain-name' lookup on any of 3 alternate servers: # ripe.net, cw.net, radb.net @@ -10,15 +11,17 @@ # ln -s /usr/local/bin/wh /usr/local/bin/wh-cw # ln -s /usr/local/bin/wh /usr/local/bin/wh-radb +E_NOARGS=65 + if [ -z "$1" ] then echo "Usage: `basename $0` [domain-name]" - exit 65 + exit $E_NOARGS fi -case `basename $0` in -# Checks script name and calls proper server +# Check script name and call proper server. +case `basename $0` in # Or: case ${0##*/} in "wh" ) whois $1@whois.ripe.net;; "wh-ripe") whois $1@whois.ripe.net;; "wh-radb") whois $1@whois.radb.net;; diff --git a/LDP/guide/docbook/abs-guide/ex3.sh b/LDP/guide/docbook/abs-guide/ex3.sh index f2421386..954c995e 100644 --- a/LDP/guide/docbook/abs-guide/ex3.sh +++ b/LDP/guide/docbook/abs-guide/ex3.sh @@ -4,10 +4,12 @@ # No argument checking. # # You might wish to add something like: +# +# E_NOARGS=65 # if [ -z "$1" ] # then # echo "Usage: `basename $0` target-file" -# exit 65 +# exit $E_NOARGS # fi @@ -25,4 +27,7 @@ sed -e /^$/d "$1" # Quoting the command-line arg permits #+ whitespace and special characters in the filename. +# Note that this script doesn't actually change the target file. +# If you need to do that, redirect its output. + exit 0 diff --git a/LDP/guide/docbook/abs-guide/ex47.sh b/LDP/guide/docbook/abs-guide/ex47.sh index 7fcc20c2..bd3a7462 100644 --- a/LDP/guide/docbook/abs-guide/ex47.sh +++ b/LDP/guide/docbook/abs-guide/ex47.sh @@ -22,7 +22,7 @@ printf "%s %s \n" $Message1 $Message2 echo # ==========================================# -# Simulation of C function, 'sprintf'. +# Simulation of C function, sprintf(). # Loading a variable with a formatted string. echo @@ -33,7 +33,7 @@ echo "Pi to 12 decimal places = $Pi12" Msg=`printf "%s %s \n" $Message1 $Message2` echo $Msg; echo $Msg -# As it happens, the 'sprintf' function can now be accessed -# as a loadable module to Bash, but this is not portable. +# As it happens, the 'sprintf' function can now be accessed +#+ as a loadable module to Bash, but this is not portable. exit 0 diff --git a/LDP/guide/docbook/abs-guide/ex48.sh b/LDP/guide/docbook/abs-guide/ex48.sh index d84f52c8..b24148a8 100644 --- a/LDP/guide/docbook/abs-guide/ex48.sh +++ b/LDP/guide/docbook/abs-guide/ex48.sh @@ -2,6 +2,11 @@ # Copying a directory tree using 'cpio.' +# Advantages of using 'cpio': +# Speed of copying. It's faster than 'tar' with pipes. +# Well suited for copying special files (named pipes, etc.) +#+ that 'cp' may choke on. + ARGS=2 E_BADARGS=65 @@ -18,7 +23,11 @@ find "$source" -depth | cpio -admvp "$destination" # ^^^^^ ^^^^^ # Read the 'find' and 'cpio' man page to decipher these options. -# It may be useful to check the exit status ($?) here -#+ to see if everything worked all right. + +# Exercise: +# -------- + +# Add code to check the exit status ($?) of the 'find | cpio' pipe +#+ and output appropriate error messages if anything went wrong. exit 0 diff --git a/LDP/guide/docbook/abs-guide/ex55.sh b/LDP/guide/docbook/abs-guide/ex55.sh index 20765bce..f8e47b4f 100644 --- a/LDP/guide/docbook/abs-guide/ex55.sh +++ b/LDP/guide/docbook/abs-guide/ex55.sh @@ -3,39 +3,40 @@ # --> Comments added by the author of this document marked by "# -->". # --> This is part of the 'rc' script package -# --> by Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org> +# --> by Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>. -# --> This particular script seems to be Red Hat specific +# --> This particular script seems to be Red Hat / FC specific # --> (may not be present in other distributions). -# Bring down all unneeded services that are still running (there shouldn't -# be any, so this is just a sanity check) +# Bring down all unneeded services that are still running +#+ (there shouldn't be any, so this is just a sanity check) for i in /var/lock/subsys/*; do # --> Standard for/in loop, but since "do" is on same line, # --> it is necessary to add ";". - # Check if the script is there. - [ ! -f $i ] && continue - # --> This is a clever use of an "and list", equivalent to: - # --> if [ ! -f "$i" ]; then continue + # Check if the script is there. + [ ! -f $i ] && continue + # --> This is a clever use of an "and list", equivalent to: + # --> if [ ! -f "$i" ]; then continue - # Get the subsystem name. - subsys=${i#/var/lock/subsys/} - # --> Match variable name, which, in this case, is the file name. - # --> This is the exact equivalent of subsys=`basename $i`. + # Get the subsystem name. + subsys=${i#/var/lock/subsys/} + # --> 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 (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. - if [ -f /etc/rc.d/init.d/$subsys.init ]; then - /etc/rc.d/init.d/$subsys.init stop - else - /etc/rc.d/init.d/$subsys stop + # Bring the subsystem down. + if [ -f /etc/rc.d/init.d/$subsys.init ]; then + /etc/rc.d/init.d/$subsys.init stop + else + /etc/rc.d/init.d/$subsys stop # --> Suspend running jobs and daemons. # --> Note that "stop" is a positional parameter, # -->+ not a shell builtin. - fi + fi done diff --git a/LDP/guide/docbook/abs-guide/ex68.sh b/LDP/guide/docbook/abs-guide/ex68.sh index 92ac82dd..8776ddde 100644 --- a/LDP/guide/docbook/abs-guide/ex68.sh +++ b/LDP/guide/docbook/abs-guide/ex68.sh @@ -1,11 +1,11 @@ #!/bin/bash -# sieve.sh +# sieve.sh (ex68.sh) # Sieve of Eratosthenes # Ancient algorithm for finding prime numbers. -# This runs a couple of orders of magnitude -# slower than the equivalent C program. +# This runs a couple of orders of magnitude slower +#+ than the equivalent program written in C. LOWER_LIMIT=1 # Starting with 1. UPPER_LIMIT=1000 # Up to 1000. @@ -33,8 +33,8 @@ do Primes[i]=$PRIME let "i += 1" done -# Assume all array members guilty (prime) -# until proven innocent. +# Assume all array members guilty (prime) +#+ until proven innocent. } print_primes () @@ -89,11 +89,14 @@ done } +# ============================================== +# main () # Invoke the functions sequentially. initialize sift print_primes # This is what they call structured programming. +# ============================================== echo @@ -104,8 +107,8 @@ exit 0 # ----------------------------------------------- # # Code below line will not execute. -# This improved version of the Sieve, by Stephane Chazelas, -# executes somewhat faster. +# This improved version of the Sieve, by Stephane Chazelas, +#+ executes somewhat faster. # Must invoke with command-line argument (limit of primes). diff --git a/LDP/guide/docbook/abs-guide/file-info.sh b/LDP/guide/docbook/abs-guide/file-info.sh index 81e8a10c..b65867b0 100644 --- a/LDP/guide/docbook/abs-guide/file-info.sh +++ b/LDP/guide/docbook/abs-guide/file-info.sh @@ -1,11 +1,11 @@ #!/bin/bash # fileinfo.sh -FILES="/usr/sbin/privatepw +FILES="/usr/sbin/accept /usr/sbin/pwck -/usr/sbin/go500gw +/usr/sbin/chroot /usr/bin/fakefile -/sbin/mkreiserfs +/sbin/badblocks /sbin/ypbind" # List of files you are curious about. # Threw in a dummy file, /usr/bin/fakefile. @@ -22,6 +22,8 @@ do ls -l $file | awk '{ print $9 " 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. echo done diff --git a/LDP/guide/docbook/abs-guide/idelete.sh b/LDP/guide/docbook/abs-guide/idelete.sh index badd98c8..b48b0719 100644 --- a/LDP/guide/docbook/abs-guide/idelete.sh +++ b/LDP/guide/docbook/abs-guide/idelete.sh @@ -23,7 +23,9 @@ fi inum=`ls -i | grep "$1" | awk '{print $1}'` # inum = inode (index node) number of file +# ---------------------------------------------------------------------- # 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. diff --git a/LDP/guide/docbook/abs-guide/multiple-processes.sh b/LDP/guide/docbook/abs-guide/multiple-processes.sh index ea73388f..29b0215d 100644 --- a/LDP/guide/docbook/abs-guide/multiple-processes.sh +++ b/LDP/guide/docbook/abs-guide/multiple-processes.sh @@ -58,7 +58,7 @@ trap - SIGRTMIN exit $? -: << SCRIPT_AUTHOR_COMMENTS +: <<SCRIPT_AUTHOR_COMMENTS I had the need to run a program, with specified options, on a number of different files, using a SMP machine. So I thought [I'd] keep running a specified number of processes and start a new one each time . . . one diff --git a/LDP/guide/docbook/abs-guide/online.sh b/LDP/guide/docbook/abs-guide/online.sh index 00fe9514..87a84246 100644 --- a/LDP/guide/docbook/abs-guide/online.sh +++ b/LDP/guide/docbook/abs-guide/online.sh @@ -79,4 +79,4 @@ done echo "On-line" # Exercise: Discuss the relative strengths and weaknesses -#! of each of these various approaches. +# of each of these various approaches. diff --git a/LDP/guide/docbook/abs-guide/param-sub.sh b/LDP/guide/docbook/abs-guide/param-sub.sh index 5e13e86f..f8de3341 100644 --- a/LDP/guide/docbook/abs-guide/param-sub.sh +++ b/LDP/guide/docbook/abs-guide/param-sub.sh @@ -6,18 +6,38 @@ #+ even if the variable is null. username0= -# username0 has been declared, but is set to null. +echo "username0 has been declared, but is set to null." echo "username0 = ${username0-`whoami`}" # Will not echo. +echo + +echo username1 has not been declared. echo "username1 = ${username1-`whoami`}" -# username1 has not been declared. # Will echo. username2= -# username2 has been declared, but is set to null. +echo "username2 has been declared, but is set to null." echo "username2 = ${username2:-`whoami`}" +# ^ # Will echo because of :- rather than just - in condition test. # Compare to first instance, above. + +# ============================================================= + +# Reiterating: + +variable= +# variable has been declared, but is set to null. + +echo "${variable-0}" # (no output) +echo "${variable:-1}" # 1 +# ^ + +unset variable + +echo "${variable-2}" # 2 +echo "${variable:-3}" # 3 + exit 0 diff --git a/LDP/guide/docbook/abs-guide/random-test.sh b/LDP/guide/docbook/abs-guide/random-test.sh index f5d050de..a9d8878c 100644 --- a/LDP/guide/docbook/abs-guide/random-test.sh +++ b/LDP/guide/docbook/abs-guide/random-test.sh @@ -4,7 +4,7 @@ RANDOM=$$ # Reseed the random number generator using script process ID. PIPS=6 # A die has 6 pips. -MAXTHROWS=600 # Increase this, if you have nothing better to do with your time. +MAXTHROWS=600 # Increase this if you have nothing better to do with your time. throw=0 # Throw count. ones=0 # Must initialize counts to zero, @@ -50,6 +50,8 @@ done print_result +exit 0 + # The scores should distribute fairly evenly, assuming RANDOM is fairly random. # With $MAXTHROWS at 600, all should cluster around 100, plus-or-minus 20 or so. # @@ -64,5 +66,3 @@ print_result # --------------- # Rewrite this script to flip a coin 1000 times. # Choices are "HEADS" and "TAILS". - -exit 0 diff --git a/LDP/guide/docbook/abs-guide/self-document.sh b/LDP/guide/docbook/abs-guide/self-document.sh index 5dd87dca..f2e8c0cc 100644 --- a/LDP/guide/docbook/abs-guide/self-document.sh +++ b/LDP/guide/docbook/abs-guide/self-document.sh @@ -11,7 +11,7 @@ then sed -e '/DOCUMENTATIONXX$/d'; exit $DOC_REQUEST; fi -: << DOCUMENTATIONXX +: <<DOCUMENTATIONXX List the statistics of a specified directory in tabular format. --------------------------------------------------------------- The command line parameter gives the directory to be listed. diff --git a/LDP/guide/docbook/abs-guide/self-source.sh b/LDP/guide/docbook/abs-guide/self-source.sh index 105dda1f..ddf4b02b 100644 --- a/LDP/guide/docbook/abs-guide/self-source.sh +++ b/LDP/guide/docbook/abs-guide/self-source.sh @@ -13,18 +13,18 @@ let "pass_count += 1" #+ can be incremented the first time around. # This works with Bash and pdksh, but #+ it relies on non-portable (and possibly dangerous) behavior. -# Better would be to set $pass_count to 0 if non-initialized. +# Better would be to initialize $pass_count to 0 before incrementing. while [ "$pass_count" -le $MAXPASSCNT ] do . $0 # Script "sources" itself, rather than calling itself. - # ./$0 (which would be true recursion) doesn't work here. + # ./$0 (which would be true recursion) doesn't work here. Why? done # What occurs here is not actually recursion, -#+ since the script effectively "expands" itself -#+ (generates a new section of code) -#+ with each pass throught the 'while' loop', +#+ since the script effectively "expands" itself, i.e., +#+ generates a new section of code +#+ with each pass through the 'while' loop', # with each 'source' in line 20. # # Of course, the script interprets each newly 'sourced' "#!" line @@ -37,4 +37,4 @@ exit 0 # The net effect is counting from 1 to 100. # Exercise: # -------- -# Write a script that uses this trick to do something useful. +# Write a script that uses this trick to actually do something useful. diff --git a/LDP/guide/docbook/abs-guide/subshell.sh b/LDP/guide/docbook/abs-guide/subshell.sh index 31dc6ec2..b18f3f0c 100644 --- a/LDP/guide/docbook/abs-guide/subshell.sh +++ b/LDP/guide/docbook/abs-guide/subshell.sh @@ -4,7 +4,7 @@ echo echo "Subshell level OUTSIDE subshell = $BASH_SUBSHELL" -# Bash, version 3, adds the new $BASH_SUBSELL variable. +# Bash, version 3, adds the new $BASH_SUBSHELL variable. echo outer_variable=Outer diff --git a/LDP/guide/docbook/abs-guide/usb.sh b/LDP/guide/docbook/abs-guide/usb.sh index 7aa07749..b580046c 100644 --- a/LDP/guide/docbook/abs-guide/usb.sh +++ b/LDP/guide/docbook/abs-guide/usb.sh @@ -2,6 +2,9 @@ # ==> usb.sh # ==> Script for mounting and installing pen/keychain USB storage devices. # ==> Runs as root at system startup (see below). +# ==> +# ==> Newer Linux distros (2004 or later) autodetect +# ==> and install USB pen drives, and therefore don't need this script. # This code is free software covered by GNU GPL license version 2 or above. # Please refer to http://www.gnu.org/ for the full license text.