Learning the bash Shell, 2nd Edition by Cameron Newham & Bill Rosenblatt The unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. This page was updated June 17, 2004. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification UNCONFIRMED errors and comments from readers: {Book} I noticed that the example "fileinfo" in the file "bash.tar.Z" has an = error. Here is a few lines around the culprit for context... if [ ! -a $1 ]; then echo "file $1 does not exist." exit 1 fi The "-a" should actually be "-e" ... -a is a Bourne shell thing and a = deprecated Korn shell thing ... "-e" and "-a" are the same in ksh (-e being favored = over -a). {2} #2 under What Is a Shell?; "...-n and phonelist are arguments..." should read: "...-n is an option, phonelist is an argument..." {10} Table 1-1 Sample cd Commands; I'm no expert so I hope I'm not wasting your time.... The commands cd book/wonderland and cd ~/book/wonderland do not appear to be valid for you example. I.e. in figure 1-2 (that the commands refer to) wonderland is a file not a directory. {90} 3rd paragraph; The text says that if you define the function: function alice { echo "alice: $*" echo "$0: $1 $2 $3 $4" echo "$# arguments" } in .bash_profile you will get the same output as if you defined it in a shell script. However, this is not true. When you type "alice in wonderland" the 2nd echo statement produces: "/bin/bash: in wonderland" whereas when you run the corresponding shell script you get "alice: in wonderland" {102} 3rd paragraph; The bash construct ${variable##*/} is not quite equivalent to the unix utility basename. Example using basename computer% cd / && basename $PWD / computer% Example ${variable##*/} computer% cd / && echo ${PWD##*/} computer% [106] task 4-7; The function / script is as follows: function lsd { date=$1 ls -l | grep -i "^.\{41\}$date" | cut -c55- } The result (After correcting for differences in columns) is a list of all teh files edited in that month, not by date. The book reads: "We use the grep search utility to match the date given as the argument (in the form of MON DD,...) The problem is "date" is not assigned MON DD. Only the MON argument ($1) is. The DD argument ($2) That is not assigned to anything. simple solutions: date=$* or date=$@ This killed me because it is the first self contained script in the book that actually does something I may really use. FYI: I'm running RedHat 7 with Bash 2.04.11(1) (118) 3rd paragraph; The text used to read: ${DIR_STACK%% } It now reads: ${DIR_STACK%% *} (120) 2nd paragraph; Third line of paragraph beginning "As an example of the = operator". contruct should be construct [131] The second to last line currently reads: tab=${tab%\t} It should read: tab=${tab%"\t"} {143} In Ch. 6, in the section on "shift," on p.143, in the latest version of the "highest" script: The elif branch has the statement print 'usage: highest [-N] filename' which should read echo 'usage: highest [-N] filename' {143} Coding example in middle of page; The script, as written hangs if it is invoked without any arguments, at all (i.e. highest), because we wind up calling sort without any arguments, so it waits for input from stdin. This is easily corrected by modifying the elif to: elif [ -n "echo $1 | grep '^-' ] || [ -z $1 ]; then {144} In the code at the bottom of the page.; I am using a copy with print date 2/01. I am in the "Options with Arguments" section. The tests for the while loop performs correctly if the arguments start with a dash. Suppose that one argument contains a dash elsewhere, like a family name, then the call to grep '-' succeeds, which is not the intention. The correction is simple: add a caret to force the discovery of dash as the first character in the string (grep '^-'). In the preceding pages discussing about argument detection, the caret appears. {150} Example on bottom half of page; The example has a typo in the variable name val1. $ result1=val*val2 should read: $ result1=val1*val2 {152} Table 6-2; The ! operator is described as being a Bitwise not. In fact, I believe it operates as a *logical* not operator. Demonstration: GNU bash, version 2.05.0(8)-release (i686-pc-cygwin): $ echo $(( ! 1 )) (displays 0) $ echo $(( ! 100 )) (displays 0) $ echo $(( ! 0 )) (displays 1) {153} table 6-3 Relational Operators (continued); As in C, the ! (bang) is a Boolean or Logical not, and should be listed below && and || as such, instead of in table 6-2 Arithmetic Operators. (167) 3rd paragraph starting with "The second variation..."; This is not technically an error, but rather a point of confusion. When using a heredoc, with the variation <<- the ending label can also be indented. Unfortunately, your example format does not point this out. EOF starts in column1. It's not just newbies that are confused about this. For example, the CD-ROM that Prentice Hall distributes with their book "Unix Shells by example" Fourth edition (013147572X) contains a related error which prevents their examples from working. i.e. see /quigley_unix_files/chap14/Ex_14.56-14.68/mainprog. The standard variation << is used instead of <<- but the ending terminator is indented causing the rest of the script to be echoed. Their discussion of here docs and example 13.89 (pp. 852) points out that the ending label as well as the input can be indented as long as the <<- format is used. (181) 2nd bullet at top of page; "Double quotes ("") bypass Steps 1 through 4, plus steps 9 and 10" Should read "Double quotes ("") bypass Steps 1 through 5, plus steps 9 and 10" since tilde substitution is also ignored in double quotes [223] Second to last paragraph; This paragraph talks about the noexec option: "The last option is noexec, which reads in the shell script, checks for syntax errors, but doesn't execute anything. It's worth using if your script is syntactically complex (lots of loops, command blocks, string operators, etc.) and the bug has side effects (like creating a large file or hanging up the system)." The problem is that the last sentence is missing the single word: "also" which should be inserted after the word "It's". This is actually a serious omission because it totally changes the reader's perception of the command (or at least this reader's perception). Without that word, the sentence sounds like the noexec option is only useful for detecting logical errors, when in fact I believe the primary reason for the option is to detect syntactical errors. I believe a secondary reason is to monitor program flow which can be used to detect logical errors, such as the author mentioned. However, the lack of one word totally changes the meaning of the sentence to me. [230] Footnote; Not sure if my setup is somehow different... GNU bash, version 2.05.8(1)-release (i386-redhat-linux-gnu) but the footnote is wrong for my setup. It says: "...make sure that the last line in the file is the colon (:), i.e., no blank lines should appear after the colon." I needed to have a single blank line or else the two files would not be properly cat'ed together. The file in the download does have the additional blank line. (231) next to last case in case statement; Book shows next to last case as: !* ) eval ${cmd#!} $args ;; # pass to the shell the downloaded example code has: \!* ) eval ${cmd#!} $args ;; # pass to the shell with the ! properly escaped. (I have the 1/00 reprint) (236) The text on this page currently reads: "... and the users may not have displays that allows them to scroll back to previous pages of screen output." The verb "allow" should be in the singular. [251] The footnote reads: "...think of the umask as a number that the operating system logically ANDs with the permission given by the creating process." It should read: "..XORs with the permission given by the creating process." [247] In the fifth paragraph, the second sentence says: An easy way to perform the search is to use the file command, which we saw in Chapter 5,..., and Chapter 9, ... But I can't find the "file" command in Chapter 5, I justs find the "fileinfo" command. Is there anything wrong or just my misunderstanding? {288} Table B-8: I/O Redirectors; The appendix table does not quite match Table 7-1. There are discrepencies on lines 7 (n : even if noclobber set) and 13 (>> file : Direct file descriptor n to file; append to file if it already exists). (288) Table B8; Table B8 lists syntax for I/O-Redirection including duplication of of stdin and stderr ('n>&', 'n<&'). After examining features of I/O-Redirection of bash in detail I for myself came to the conclusion, that this duplication is not implemeted(in bash). {300} first full paragraph, 4th line in the paragraph; The word "list" should have appeared as "" in this line {305} index entry for ! (bang); The index entry for ! (bang) says: bitwise not operator, 152 it should say: logical not operator, 153 (308) There are two entries for "command command" (that is, the bash command named "command"); one italicized, one not. They refer to the same command, and should be a single entry. (January 1998 printing) [305-318] index ; There is no notation in the book / index about "no-ops" or about the "continue" function from bash. Could be that those are hidden/unsupported features but t would be nice to mention them.