diff --git a/LDP/guide/docbook/abs-guide/Change.log b/LDP/guide/docbook/abs-guide/Change.log index a54adf8f..ea5ee37f 100644 --- a/LDP/guide/docbook/abs-guide/Change.log +++ b/LDP/guide/docbook/abs-guide/Change.log @@ -6,6 +6,66 @@ http://personal.riverusers.com/~thegrendel/Change.log ------------------------------------------------------------------------ +Version 2.1 +'HUCKLEBERRY' release, 09/14/03 + +1) In Appendix B, "Reference Cards: + Fixups -- + (thanks to errors brought to my attention by Heiner Steven). + +2) In Appendix B, "Reference Cards: + Added "Miscellaneous Construct" table. + Added variable prefix matching to "Parameter Substitution" table. + +3) In "Internal Variables" chapter" + Noted that "$*" must be quoted to differentiate it from "$@" variable, + and added a case to "arglist.sh" example to demonstrate this. + (Thanks, Heiner Steven.) + +4) In "Command Substitution" chapter: + Added note about the invocation of a subshell. + Likewise added note in "setting variable to a file" in-line example. + (Thanks, Paul Heffner.) + Removed erroneous comment from in-line example of + setting a variable to contents of a file. + (Thanks, Anthony Richardson.) + +5) In "Arrays" chapter: + Added "script-array.sh" example. + (Thanks, Chris Martin, for the inspiration.) + +6) In "System Resources" subsection of "System and Administrative + Commands": + Fixed minor error ("while 1") in 'ulimit' illustrative script. + (Thanks Emmanuel Chantreau) + +7) In "Subshells" chapter: + Added a paragraph of commentary concerning external commands and Bash + builtins. + +8) In "Special Characters" chapter: + Elaborated example of ';' usage. + +9) In "Gotchas" chapter: + Added in-line example of problem caused by piping to a loop. + (Thanks Anthony Richardson.) + +10) In "System and Administrative Commands" chapter: + Added more info to "sar" listing. + +11) In "Writing Scripts" section of "Exercises" appendix: + Added "Monitoring Processes" exercise. + +12) In "Recursion" section of "Oddities" chapter: + Added Anthony Richardson's "usrmnt.sh" example. + (Thanks!) + +13) Slight modifications to certain example files for clarification. + + + + + Version 2.0 'GOOSEBERRY' release, 08/24/03 @@ -52,7 +112,7 @@ bumped up to a major version. This is now officially a "mature" project. by disabling parameter substitution within the body of a 'here document.' (Thanks, Albert Reiner, for the idea.) -10) In "Miscellaneous" subsection of "System and Administrative Commands" +10) In "Miscellaneous" subsection of "System and Administrative Commands": chapter: Added listing for "dialog" toolsets. diff --git a/LDP/guide/docbook/abs-guide/abs-guide.sgml b/LDP/guide/docbook/abs-guide/abs-guide.sgml index f512924c..8e15227d 100644 --- a/LDP/guide/docbook/abs-guide/abs-guide.sgml +++ b/LDP/guide/docbook/abs-guide/abs-guide.sgml @@ -272,6 +272,8 @@ Uncomment line below to generate index. + + @@ -294,8 +296,8 @@ Uncomment line below to generate index. - 2.0 - 24 August 2003 + 2.1 + 14 September 2003 @@ -420,8 +422,15 @@ Uncomment line below to generate index. 24 August 2003 mc 'GOOSEBERRY' release: Major update. - + + + 2.1 + 14 September 2003 + mc + 'HUCKLEBERRY' release: bugfixes and more material. + + @@ -445,7 +454,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-2.1.tar.bz2"> the author's home site. See the change log for a revision history. @@ -979,7 +988,17 @@ echo $(( 2#101011 )) # Base conversion, not a comment. the same line. - echo hello; echo there + + echo hello; echo there + + +if [ -x "$filename" ]; then # Note that "if" and "then" need separation. + # Why? + echo "File $filename exists."; cp $filename $filename.bak +else + echo "File $filename not found."; touch $filename +fi; echo "File test complete." + Note that the ; sometimes needs to be escaped. @@ -6016,9 +6035,9 @@ echo "Last command argument processed = $last_cmd_arg" The $PPID of a process is - the process id (pid) of its parent process. + the process ID (pid) of its parent process. - The pid of the currently running script is + The PID of the currently running script is $$, of course. @@ -6428,8 +6447,10 @@ echo "Last command argument processed = $last_cmd_arg" positional all - All of the positional parameters, seen as a single - word + + All of the positional parameters, seen as a single word + $* must be + quoted. @@ -6446,12 +6467,18 @@ echo "Last command argument processed = $last_cmd_arg" positional parameter all - Same as $*, but each parameter is a + + + + Same as $*, but each parameter is a quoted string, that is, the parameters are passed on intact, without interpretation or expansion. This means, among other things, that each parameter in the argument list is seen as a separate word. + Of course, $@ + should be quoted. + <command>arglist</command>: Listing arguments with $* and $@ &arglist; @@ -9607,7 +9634,7 @@ do operation-2 ... operation-n - # Need a way to break out of loop. + # Need a way to break out of loop or script will hang. done @@ -9993,7 +10020,7 @@ wait process, that is, a process whose parent has terminated, cannot be killed (you can't kill something that is already dead), - but init will usually clean it up + but init will generally clean it up sooner or later. @@ -10159,6 +10186,8 @@ wait External Filters, Programs and Commands + + Standard UNIX commands make shell scripts more versatile. The power of scripts comes from coupling system commands and shell directives with simple programming constructs. @@ -16366,11 +16395,13 @@ exit 0 system activity report - Invoking sar (system activity report) - gives a very detailed rundown on system statistics. - This command is found on some commercial UNIX - systems, but is not part of the base Linux - distribution. It is contained in the Invoking sar (System Activity Reporter) + gives a very detailed rundown on system statistics. The + Santa Cruz Operation (SCO) released + sar as Open Source in June, 1999. + + This command is not part of the base Linux distribution, + but may be obtained as part of the sysstat utilities package, written by Sebastien @@ -16519,7 +16550,7 @@ exit 0 Process Statistics: lists currently - executing processes by owner and PID (process id). This + executing processes by owner and PID (process ID). This is usually invoked with options, and may be piped to grep or sed to search for a @@ -16632,12 +16663,12 @@ exit 0 process id - Identifies process id (pid) of a + Identifies process ID (PID) of a running job. Since job control commands, such as kill and renice - act on the pid of a process (not + act on the PID of a process (not its name), it is sometimes necessary to identify that - pid. The pidof + PID. The pidof command is the approximate counterpart to the $PPID internal variable. @@ -16665,7 +16696,7 @@ exit 0 fuser - Identifies the processes (by pid) that are accessing + Identifies the processes (by PID) that are accessing a given file, set of files, or directory. May also be invoked with the option, which kills those processes. This has interesting implications for @@ -17552,8 +17583,10 @@ then #!/bin/bash +# This script is for illustrative purposes only. +# Run it at your own peril -- it *will* freeze your system. -while 1 # Endless loop. +while true # Endless loop. do $0 & # This script invokes itself . . . #+ forks an infinite number of times . . . @@ -17620,7 +17653,7 @@ exit 0 # Will not exit here, because this script will never terminate.Get info about or make changes to root device, swap space, or video mode. The functionality of rdev has generally been taken over by lilo, but rdev remains - useful for setting up a ram disk. This is another dangerous command, if misused. + useful for setting up a ram disk. This is a dangerous command, if misused. @@ -17957,6 +17990,10 @@ echo $textfile_listing2 # Thanks, S.C. + Command substitution invokes a subshell. + + Command substitution may result in word splitting. COMMAND `echo a b` # 2 args: a and b @@ -18043,13 +18080,12 @@ echo "$dir_listing" # quoted linkend="catref">cat command. - variable1=`<file1` # Set "variable1" to contents of "file1". -variable2=`cat file2` # Set "variable2" to contents of "file2". + variable1=`<file1` # Set "variable1" to contents of "file1". +variable2=`cat file2` # Set "variable2" to contents of "file2". + # This, however, forks a new process, + #+ so the line of code executes slower than the above version. -# Note 1: -# Removes newlines. -# -# Note 2: +# Note: # The variables may contain embedded whitespace, #+ or even (horrors), control characters. @@ -18159,7 +18195,6 @@ File_contents1=$(cat $file1) File_contents2=$(<$file2) # Bash permits this also. - Examples of command substitution in shell scripts: @@ -19627,9 +19662,19 @@ echo a111b | gawk '/a1+b/' subshells let the script do parallel processing, in effect executing multiple subtasks simultaneously. - + + + In general, an external + command in a script forks + off a subprocess, whereas a Bash builtin does not. For this reason, + builtins execute more quickly than their external command + equivalents. + + - <anchor id="subshellparens1">Command List in Parentheses + <anchor id="subshellparens1">Command List in + Parentheses ( command1; command2; command3; ... ) @@ -20733,6 +20778,14 @@ echo ${array2[2]} # echo ${array2[3]} # fourth element + Command substitution can + construct the individual elements of an array. + + + Loading the contents of a script into an array + &scriptarray; + + In an array context, some Bash builtins have a slightly altered meaning. For example, unset @@ -22005,11 +22058,55 @@ exit 0 &badread; + In fact, as Anthony Richardson points out, piping to + any loop can cause a similar problem. + + +# Loop piping troubles. +# This example by Anthony Richardson. + + +foundone=false +find $HOME -type f -atime +30 -size 100k | +while true +do + read f + echo "$f is over 100KB and has not been accessed in over 30 days" + echo "Consider moving the file to archives." + foundone=true +done + +# foundone will always be false here since it is +#+ set to true inside a subshell +if [ $foundone = false ] +then + echo "No files need archiving." +fi + +# =====================Now, here is the correct way:================= + +foundone=false +for f in $(find $HOME -type f -atime +30 -size 100k) # No pipe here. +do + echo "$f is over 100KB and has not been accessed in over 30 days" + echo "Consider moving the file to archives." + foundone=true +done + +if [ $foundone = false ] +then + echo "No files need archiving." +fi + + + -- + Using suid commands within scripts is risky, as it may compromise system security. Setting the suid permission on the script itself has no effect. - + + Using shell scripts for CGI programming may be problematic. Shell script variables are not typesafe, and this can cause @@ -22478,6 +22575,11 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" # Greater ASCI &pbook; + + Another (useful) script that recursively calls itself + &usrmnt; + + Too many levels of recursion can exhaust the script's stack space, causing a segfault. @@ -23337,12 +23439,13 @@ fi good book on the subject? I was looking to buy a tutorial and reference covering all aspects of the subject. I was looking for a book that would take difficult concepts, turn them inside out, and - explain them in excruciating detail with well-commented examples. + explain them in excruciating detail, with well-commented examples. This is the notorious flog it to death technique. - In fact, I was looking for this very book, or something much - like it. Unfortunately, it didn't exist, and if I wanted it, - I'd have to write it. And so, here we are, folks. + In fact, I was looking for this very book, + or something much like it. Unfortunately, it didn't exist, + and if I wanted it, I'd have to write it. And so, here we are, + folks. This reminds me of the apocryphal story about the mad professor. Crazy as a loon, the fellow was. At the sight of a @@ -23353,7 +23456,7 @@ fi 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 + 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... @@ -23373,7 +23476,7 @@ fi HOW-2 Meet Women: The Shy Man's Guide to Relationships. He has also written the Software-Building - HOWTO. + HOWTO. Lately, he has been trying his hand at short fiction. A Linux user since 1995 (Slackware 2.2, kernel 1.2.1), the author has emitted a few @@ -23543,11 +23646,11 @@ fi 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, - Emilio Conti, Dennis Leeuw, Dan Jacobson, Aurelio Marinho Jargas, - Edward Scholtz, Jean Helou, and David Lawyer (himself an author - of 4 HOWTOs). + Keith Matthews, Sandro Magi, Albert Reiner, Dim Segebart, Rory + Winston, Lee Bigelow, Wayne Pollock, jipe, Emilio + Conti, Dennis Leeuw, Dan Jacobson, Aurelio Marinho Jargas, + Edward Scholtz, Jean Helou, Chris Martin, and David Lawyer + (himself an author of 4 HOWTOs). My gratitude to Chet Ramey and Brian Fox for writing Bash, @@ -24341,6 +24444,10 @@ fi Reference Cards + The following reference cards provide a useful + summary of certain scripting concepts. + The foregoing text treats these matters in more depth and gives + usage examples. Special Shell Variables @@ -24373,11 +24480,11 @@ fiNumber of positional parameters - - All the positional parameters (as a single word) + + All the positional parameters (as a single word) * - + All the positional parameters (as separate strings) @@ -24415,6 +24522,9 @@ fi
+ * Must be quoted, + otherwise it defaults to + $@. @@ -24459,7 +24569,7 @@ fiNot equal to - + Not equal to @@ -24670,6 +24780,7 @@ fi Value of var, same as $var + If var not set, evaluate expression @@ -24677,9 +24788,11 @@ fi - If var not set, evaluate expression - as $DEFAULT * + If var not set or is empty, + evaluate expression as $DEFAULT + * + If var not set, evaluate expression @@ -24690,6 +24803,7 @@ fi If var not set, evaluate expression as $DEFAULT * + If var set, evaluate expression as @@ -24700,6 +24814,7 @@ fi If var set, evaluate expression as $OTHER, otherwise as null string + If var not set, print @@ -24710,6 +24825,17 @@ fi If var not set, print $ERR_MSG * + + + + Matches all previously declared variables beginning with + varprefix + + + + Matches all previously declared variables beginning with + varprefix +
@@ -24735,12 +24861,12 @@ fi - + Extract substring from $string at $position - + Extract $length characters substring from $string at $position @@ -24856,6 +24982,120 @@ fi regular expression.
+ + + Miscellaneous Constructs + + + + + Expression + Interpretation + + + + + + Brackets + + + + Test construct + + + + Extended test construct + + + + Array initialization + + + + Range of characters within a Regular Expression + + + + Curly Brackets + + + + Parameter substitution + + + + Indirect variable reference + + + + Block of code + + + + Brace expansion + + + + + Parentheses + + + + Command group executed within a subshell + + + + Array initialization + + + + Execute command in subshell and assign result to + variable + + + + Process substitution + + + + Process substitution + + + + Double Parentheses + + + + Integer arithmetic + + + + Integer arithmetic, with variable assignment + + + + Quoting + + + + "Weak" quoting + + + + "Strong" quoting + + + + Back Quotes + + + + Execute command in subshell and assign result to variable + + + +
+ @@ -26484,6 +26724,20 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612
+ + Monitoring Processes + + Write a script to continually monitor all running + processes and to keep track of how many child processes each + parent spawns. If a process spawns more than five children, + then the script sends an e-mail to the system administrator + (or root) with all relevant information, including the + time, PID of the parent, PIDs of the children, etc. The + script writes a report to a log file every ten minutes. + + + + Strip Comments @@ -26886,6 +27140,7 @@ B. Distribution of the work or derivative of the work in any standard Linux is a trademark registered to Linus Torvalds. Unix and UNIX are trademarks registered to the Open Group. MS Windows is a trademark registered to the Microsoft Corp. + Scrabble is a trademark registered to Hasbro, Inc. All other commercial trademarks mentioned in the body of this work are registered to their respective owners. diff --git a/LDP/guide/docbook/abs-guide/arglist.sh b/LDP/guide/docbook/abs-guide/arglist.sh index cdf3636f..04ba419c 100644 --- a/LDP/guide/docbook/abs-guide/arglist.sh +++ b/LDP/guide/docbook/abs-guide/arglist.sh @@ -1,4 +1,5 @@ #!/bin/bash +# arglist.sh # Invoke this script with several arguments, such as "one two three". E_BADARGS=65 @@ -35,4 +36,12 @@ echo "Arg list seen as separate words." echo +echo "Listing args with \$* (unquoted):" +for arg in $* +do + echo "Arg #$index = $arg" + let "index+=1" +done # Unquoted $* sees arguments as separate words. +echo "Arg list seen as separate words." + exit 0 diff --git a/LDP/guide/docbook/abs-guide/reply.sh b/LDP/guide/docbook/abs-guide/reply.sh index 3940cc53..fc5becd0 100644 --- a/LDP/guide/docbook/abs-guide/reply.sh +++ b/LDP/guide/docbook/abs-guide/reply.sh @@ -5,8 +5,8 @@ echo -n "What is your favorite vegetable? " read echo "Your favorite vegetable is $REPLY." -# REPLY holds the value of last "read" if and only if -# no variable supplied. +# REPLY holds the value of last "read" if and only if +#+ no variable supplied. echo echo -n "What is your favorite fruit? " @@ -14,8 +14,8 @@ read fruit echo "Your favorite fruit is $fruit." echo "but..." echo "Value of \$REPLY is still $REPLY." -# $REPLY is still set to its previous value because -# the variable $fruit absorbed the new "read" value. +# $REPLY is still set to its previous value because +#+ the variable $fruit absorbed the new "read" value. echo diff --git a/LDP/guide/docbook/abs-guide/t-out.sh b/LDP/guide/docbook/abs-guide/t-out.sh index 4aac4867..a1faa205 100644 --- a/LDP/guide/docbook/abs-guide/t-out.sh +++ b/LDP/guide/docbook/abs-guide/t-out.sh @@ -1,7 +1,9 @@ #!/bin/bash -# t-out.sh (per a suggestion by "syngin seven) +# t-out.sh +# Inspired by a suggestion from "syngin seven" (thanks). -TIMELIMIT=4 # 4 seconds + +TIMELIMIT=4 # 4 seconds read -t $TIMELIMIT variable <&1 @@ -15,3 +17,8 @@ else fi exit 0 + +# Exercise for the reader: +# ----------------------- +# Why is the redirection (<&1) necessary in line 8? +# What happens if it is omitted?