Errata

bash Cookbook: Rough Cuts Version

Errata for bash Cookbook: Rough Cuts Version

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
Printed
Page ix (ToC)
4th line up from bottom

Page number for page ?373? not outdented correctly

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page Index
Missing entry

The index is missing: $''
(e.g., used in setting IFS=$'')
Page 281

(maybe other uses too?)


Suggested entry:

$'' (IFS=$' \t\n'), 281

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Page xvi
3rd paragraph

", and we have used it that way in some OUT our code examples."

"OUT" should be "of" ?

Note from the Author or Editor:
First, we're really sorry we never got back to this! We try to keep up on errata (we get emails), but somehow a number of them slipped through.

This is verified, I have the error in my first edition copy. But it was fixed later or in the second edition. Thanks for the report though!

mark chang  Jul 21, 2016 
Printed
Page 5
2nd line of Discussion

"... is the default.s displays your..." is wrong, should be
"... is the default. -P displays your physical..."

Also, add a new sent. at end of para.: "The 'cd' command also provides the -P and -L switches."

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 5
Second sentence in Discussion paragraph

The second sentence reads "-L displays your logical path and is the default.s displays your physical
location, ..." Probably should read "-L displays your logical path and is the default. -P displays your
physical location, ..."

Anonymous    Nov 15, 2013
Printed
Page 7
Mid page

Replace: ?For much more on the find?
With: ?For details on the find?

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 7
Middle of the page

The sentence "For much more on the find command, ..." is a bit disconcerting because nothing at all has
been said about the find command

(61) func_choose

Add a trailing
in the example near the middle of the page:
# 'printf "%b" "See you later Professor Falkin.
"' >&2

Replace "exec" with "eval" in 2 lines at the bottom of the page:
[yY1] ) eval "$choice_yes"
[nN0] ) eval "$choice_no"

{pg62} func_choice.2

"until [ "$CHOICE" = "y" ]; do"

If CHOICE is already set, it won't prompt.
You may want to unset the var.

Add "CHOICE=''"
# cookbook filename: func_choice.2
CHOICE=''
until [ "$CHOICE" = "y" ]; do

Anonymous    Nov 15, 2013
Printed
Page 11
In the middle--Warning

The two lines(counting from the bottom of page, Line 9 & 10

Line 10: ..foo .a .normal_dot_file
Line 9: normal_dot_file

To me, the above two lines should not be there(should not exist).
Am I wrong?

Note from the Author or Editor:
You are correct, thanks for the report. I'm not sure how those lines got in there, possibly a copy&paste error. But they should both be removed.

For clarity, here is the correct example, with a 'touch' line added at the top:

$ touch ..foo .a .normal_dot_file normal_file

$ ls -a
. .. ..foo .a .normal_dot_file normal_file

$ ls -d .??*
..foo .normal_dot_file

$ ls -d .[!.]*
.a .normal_dot_file

$ ls -d .[!.]* .??* | sort -u
..foo
.a
.normal_dot_file

Seung Bae Im  Dec 18, 2009  Nov 15, 2013
ePub
Page 15
Conventions Used In This Book: Plain Text

The convention tect "Plain text" doesn't appear in plain text. It appears in Italic text exactly like the next convention.

Andrei Freeman  Aug 30, 2012  Nov 15, 2013
PDF
Page 32
last code sampel on page

The printf output in the last example on page 32 is wrong.

It has three spaces between the "=" and the "1.93" but there should be only one.

The book output is:

GigaHerz = 1.93

The correct output is:
GigaHerz = 1.93


Note from the Author or Editor:
Correct, thanks! Well, actually (using 2x __ since spaces get squashed):
-GigaHerz = __1.93
+__GigaHerz = 1.93

That is, the 2 "extra" spaces move from before "1.93" to before "GigaHerz".

The code is correct, the displayed output is wrong. Fixed in SVN 731332.

scott field  Dec 17, 2013 
Printed
Page 38
Line 14

single entry, indicating that standard output (2) will be redirected ...

The word "output" should be "error"

Note from the Author or Editor:
Correct, it should read:
single entry, indicating that standard error (2) will be redirected ...

Seung Bae Im  Dec 21, 2009  Nov 15, 2013
Printed
Page 40
Recipe 2.12

+2 is not a valid tail option and will throw an error unless there is a file named +2

tail: cannot open `+2' for reading: No such file or directory

See man (1) tail

The proper syntax would be tail -n +2

Note from the Author or Editor:
Great catch! This happened because the system I mostly used for testing was Debian Sarge (3.1 kernel 3.6.8) with a version of tail (coreutils) 5.2.1 (c) 2004 that *does* allow that syntax, which I just verified in a VM I have. That said, nothing else these days dos allow that, and it was sloppy to begin with.

So this and any other instances of 'tail +' should be changed to 'tail -n +'.

Maine_guy  Sep 20, 2012  Nov 15, 2013
Printed
Page 53
Middle, See also section

the web address is incorrect.
http://www.comptechdoc.org/os/linux/usersguide/linux_ugfilesup.html
should be
http://www.comptechdoc.org/os/linux/usersguide/linux_ugfilesp.html

_ugfilesup.html should not have the 2nd u just before p.html.

Note from the Author or Editor:
Remove extra 'u' as noted.

Anonymous    Nov 15, 2013
Printed
Page 58
Code under solution

Eighth release

the code for cat ext shows:

here is a "here" document
# grep $1 <<EOF

shouldn't the # comment tag be placed on the "here is" line and removed from the "grep" line? It only works when I make this change.

Note from the Author or Editor:
You are correct. What is really interesting is that in my first edition dead tree version, this is on page 56 and is correct. So somewhere down the line in one of the (many) format conversions this one crept in there. Thanks for letting us know.

Note to production: fixed in SVN 798323.

Mark Fritchen  Sep 06, 2015 
Printed
Page 60
in the "Solution" section

There should be no space between the "-" and the "p"

read - p "answer me this " ANSWER
read -p "answer me this " ANSWER

Note from the Author or Editor:
Remove extra space.

Anonymous    Nov 15, 2013
Printed
Page 61
Mid page and bottom

Mid page: Missing '\n' after "Falkin"
Add like: Professor Falkin.\n"'

Near bottom:
Replace 2 instances of 'exec' with 'eval'

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 62
In script: func_choice.1

Replace: ?$ Returns? With: ?# Returns?

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 62
In script: func_choice.2

2 issues

1) Add this line right above 2nd line of script ?until [ ?$CHOICE...? (note 2 trailing single quotes on new line): CHOICE=''

2) 5 lines up from bottom, add space in ?$THISPACKAGE with?

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 62
func_choice.2

"$THISPACKAGEwith"

There should be a space.

Add a space in "$THISPACKAGE with":
elif [ "$CHOICE" != "y" ]; then
printf "%b" "Overriding $THISPACKAGE with ${CHOICE}
"
THISPACKAGE=$CHOICE

Anonymous    Nov 15, 2013
Printed
Page 62
func_choice.1

"$ Returns: global variable CHOICE"

$ should be #.

"# Returns: global variable CHOICE"

Anonymous    Nov 15, 2013
Printed
Page 63
In script: func_choice.3

Add \n inside quotes in both printf statements, e.g,

... $CHOICE\n"
... color.\n"

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 63
func_choice.3

_printf "%b" "You chose: $CHOICE"_
_printf "%b" "You do not have a favorite color."_

Need "
".

Add "
", should look look like:
printf "%b" "You chose: $CHOICE
"
printf "%b" "You do not have a favorite color.
"

Anonymous    Nov 15, 2013
Printed
Page 64
In script: select_dir

3 issues

1) In second line of script replace $(ls /)?
With: $(for I in /*; do [ -d "$i" ] && echo $i; done)


2) Inconsistent '=' and '=='
In middle of script replace '=' with '==' in if[] statement


3) Fix comment in last line of script:
Replace: done # end of while not finished
with: done # end of until dir == finished

Note from the Author or Editor:
Thanks to ?Nits? in http://morlockhq.blogspot.com/2008/08/book-review-bash-cookbook.html for parts of this report

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 64
select_dir

Replace:
directorylist="Finished $(ls /)"
with
directorylist="Finished $(for i in /*;do [ -d "$i" ] && echo $i; done)"

Anonymous    Nov 15, 2013
PDF
Page 65
1st paragraph (code)

Code specifies incorrect case of variable name in two places

if [ "$choice" != "n" ]; then
...
if [ "$choice" = "y" ]; then

should be

if [ "$CHOICE" != "n" ]; then
...
if [ "$CHOICE" = "y" ]; then

Note from the Author or Editor:
Wow, how have we missed that one for so long!? Thanks!

Note to production: fixed in SVN 798322.

Bryan Hanks, PMP  Sep 11, 2015 
Printed
Page 66
Sydney

Very first sentence, in the animal trap "warning" message:

Change "Some older scripts may use s to disable"
to
"Some older scripts may use stty -echo to disable"

Note from the Author or Editor:
OO.o manuscript contained "Some older scripts may use stty to disable...", note "stty" and not just "s". But I like Stuart Cooper's more specific version better.

So please change to: "Some older scripts may use <command>stty -echo</command> to disable..."

Stuart Cooper  Oct 20, 2011  Nov 15, 2013
Printed
Page 74
Solution

Replace: (( $? ))
With: (( $? == 0 ))

Note from the Author or Editor:
Thanks to M. Wang and B. McElvaney for this report

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 74 and 75
the code fragment

if (( $? )); then rm * ; fi

Should be:
if (( $? == 0 )); then rm * ; fi
or:
if (( ! $? )); then rm * ; fi

Anonymous    Nov 15, 2013
Printed
Page 75
Example in Discussion

[Same as pg 74]

Replace: (( $? ))
With: (( $? == 0 ))

Note from the Author or Editor:
Thanks to M. Wang and B. McElvaney for this report

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 84
Discussion 3rd para

?Thought? --> ?Though?

Note from the Author or Editor:
Thanks to ?Nits? in http://morlockhq.blogspot.com/2008/08/book-review-bash-cookbook.html for this report

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 93
Last paragraph

In the line beginning "When we quoted..." the reference is referred to as "{$1}". It should be "${1}"

Note from the Author or Editor:
Change to ${1} as noted.

Anonymous    Nov 15, 2013
Printed
Page 98
5.12.2 Solution

The script if test clause is doing the opposit the author meant it to do, which is to have a verbose
output when -v is an argument
Instead of: if (( VERBOSE == 0 ))
The script should read: if (( VERBOSE == 1 ))

Note from the Author or Editor:
Change instance in "if" statement to "if (( VERBOSE == 1 ))" as noted.

Anonymous    Nov 15, 2013
Printed
Page 99
Solution

Bad double quotes in: FILEDIR=${1-"/tmp"}
Remove both double quotes

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 105/6
Bottom

On page 105 we are given:
mv "${FN}" "${FN/.bad/.bash}"
even though this kind of substitution is not anchored the example given on page 106 : "subaddon.bad would leave us with subashdon.bad" is wrong this would have only occured if the line on page 105 read:
mv "${FN}" "${FN/bad/bash}" (without the "." period characters).

The outcome for the example given on page 106 from the line that is actually printed on page 105 would have resulted in subaddon.bash which is what we would have needed.

Note from the Author or Editor:
I agree, nice catch.

To fix:
1) On pg 105, add comment and remove the dots in the mv example at bottom:
mv "${FN}" "${FN/.bad/.bash}"
becomes
# Not anchored, don't do this
mv "${FN}" "${FN/bad/bash}"

2) On pg 106, at end of 1st para add:
Using a dot anchored expression like this would work in the example case:
# Anchored, so this is better, but TEST first
mv "${FN}" "${FN/.bad/.bash}"

Anonymous  Nov 24, 2008  Nov 15, 2013
Printed
Page 123
code example, line 6

The shell option compat31 must be set for the expression to the right of the =~ operator to work with quotes. Otherwise, no quotes should be used to the right of the =~ but the spaces would need to be escaped (with backslashes).

Either the command:
shopt -s compat31
should be executed first (e.g., line 4) or the "if" statement should be:

if [[ "$CDTRACK" =~ ([[:alpha:][:blank:]]*)-\ ([[:digit:]]*)\ -\ (.*)$ ]]

(which is the same as printed EXCEPT there are no quotes on the right hand side but each space is preceeded by a backslash). The quotes around the variable "$CDTRACK" on the left hand side are very much needed in all cases.

Similarly in the "Caution:" section below the code example, the escaping of the parentheses and dollar sign will not work unless the compat31 option is set. Alternately, removing those backslashes (but not the ones for escaping the spaces) will work.

Carl Albing
 
Feb 08, 2011  Nov 15, 2013
Printed
Page 134
Problem

It reads:
dashes -c= 50
dashes -cx
whereas it should have read:
dashes -c = 50
dasshes -c x

Note from the Author or Editor:
Agree, should add a space after the "-c" part to read:

dashes -c = 50
dashes -c x

Anonymous  Oct 06, 2008  Nov 15, 2013
Printed
Page 134
Problem

Missing spaces after -c
Add space as: ?-c =? and ?-c x?

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
PDF
Page 136
See Also

It mentions in "see also"
? help getopts
? help getopt

There is only getopts AFAIK, at-least in my bash (version 4.1.10(4)-release)

Note from the Author or Editor:
Confirmed, 'getopts' is correct; 'getopt' is my mistake. I very much fear I was thinking of Perl when I added that one. :-/

"help getopt" (note, no 's') should be removed.

Anonymous  Jul 21, 2011  Nov 15, 2013
Printed
Page 139
script dbinit.2

The script as written does not properly increment the number of inits. After the first time through the loop, the PS3 prompt is still 0 inits. giving an erroneous total at each step.

The problem is with the code line
PS3="$((i++)) inits >"

i++ is a post increment operator. The working variable i starts off being uninitialized. Dereferencing i with $((i++)) the first time through the loop returns 0 and sets i to 1. The 0 becomes part of PS3.

The operator should be pre increment. Dereferencing the uninitialized variable with $((++i)) returns 1 and sets i to 1 so the prompt will be correct the first time through the loop.

unset i # i is uninitialized
echo $((i++)) # prints 0
echo $i # prints 1

unset i # i is uninitialized
echo $((++i)) # prints 1
echo $i # also prints 1

Note from the Author or Editor:
Correct! The $((i++)) should be changed to $((++i)). Should I also email an updated examples tarball or can production take care of that too?

Maine_guy  Sep 20, 2012  Nov 15, 2013
Printed
Page 155
See also

Add x-refs to 8.4, 13.12

Note from the Author or Editor:
Thanks to ?Nits? in http://morlockhq.blogspot.com/2008/08/book-review-bash-cookbook.html for this report

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 185
7 paragraph from top, 2nd paragraph from bottom

2nd sentence
"The remainder of the lineup to the ; is the command to be executed."
should be
"The remainder of the line, up to the ;, is the command to be executed."

Note from the Author or Editor:
Line should have a "slash semi-colon" but this web interface might be eating the slash. Se we're talking about " \; ". Otherwise I see the point about the missing space certainly, and the commas arguably.

Anonymous    Nov 15, 2013
Printed
Page 207
1st full para

?hat? --> ?what?

Note from the Author or Editor:
Thanks to ?Nits? in http://morlockhq.blogspot.com/2008/08/book-review-bash-cookbook.html for this report

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 228
Solution

Vixiecron needs: \%

5 times change '+%a' to '+\%a'

Add an addition "beartrap" note that the \% escape might not be needed under cron systems other than Vixie.

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 228-229
11.9 Using date and cron to Run a Script on the Nth Day

Add Warning:
Vixie Cron interprets an unescaped % as a newline, so the % in '+%a'
must be escaped like '+\%a' if using Vixie Cron (e.g. most/all Linux).

Add note:
If cron seems like it's not working, try restarting your MTA (e.g.
sendmail). Some versions of cron on some systems (e.g. Vixie Cron on
Red Hat) are tied into the sendmail process. See
https://bugzilla.redhat.com/show_bug.cgi?id=247228.

Anonymous    Nov 15, 2013
Printed
Page 231
last paragraph

"... and a -c option followed by a number ..."

should likely be

"... and a -c option followed by a character ..."

Note from the Author or Editor:
Change "number" to "character" as noted.

Anonymous    Nov 15, 2013
Printed
Page 233
1st sent, last para

?fpllowing? --> ?following?

Note from the Author or Editor:
Thanks to ?Nits? in http://morlockhq.blogspot.com/2008/08/book-review-bash-cookbook.html for this report

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 243
Scripting lines 14, 23, 35 and 40 of 12.4 Burning a CD

line 14:
RCDIR=$1 should read SRCDIR=$1

line 23:
$ISOPTS has never been set before

line 35:
since you exit the script unconditionally the iso image will never get burned.

line 40:
$ISOImage should read $ISOIMAGE

Note from the Author or Editor:
Here's how the modified lines should read (only showing changed lines):
14 SRCDIR=$1
23 mkisofs -A "$(cat ~/.cdAnnotation)" \
35 #
36 # burn the CD
37 #
40 cdrecord $OPTS -speed=$SPD dev=${CDDEV} $ISOIMAGE

Anonymous    Nov 15, 2013
Printed
Page 246
lines 54, 55, 69, and 73 of the oodiff script. May 2007 printing (first edition)

The variables $PRIV1 on line 54, $PRIV2 on line 55, $HERE on line 69, and $PRIV1 $PRIV2 on line 73
all should be enclosed in double quotes. This would avoid difficulty when filenames contain spaces.

Note from the Author or Editor:
Lines 54,55 have the variable correctly double-quoted at the start of the line, but do not quite inside the echo "". Adding single-quotes around them would be useful for clarity.

Lines 69 and 73 do need double quotes around the variables.

Anonymous    Nov 15, 2013
Printed
Page 246
Lines 54,55 in script

This is an errata to an errata I just confirmed.

In the previous one I said that the echo lines were OK because they had double-quotes, but they don't.

Note from the Author or Editor:
Correct:

mkdir "$PRIV1" || { echo "Unable to mkdir '$PRIV1'" ; exit 4; }
mkdir "$PRIV2" || { echo "Unable to mkdir '$PRIV2'" ; exit 5; }

JP Vossen
JP Vossen
 
May 23, 2009  Nov 15, 2013
Printed
Page 249
Solution section of getopts_example

minus sign '-' should be used
instead of figure dash '&#8210;' within the code itself,
in getopts_example

sample code from website encounters an error too.

Note from the Author or Editor:
I can't tell the difference in the printed version, but will fix the example script.

Anonymous    Nov 15, 2013
Printed
Page 256
parseViaFunc

Was:
CRDATE=$6
CRTIME=$7
FILE=$8
}
Add "CRDAY=$7" and increment other positional variables:
CRDATE=$6
CRDAY=$7 <<< Added
CRTIME=$8
FILE=$9
}

Anonymous    Nov 15, 2013
Printed
Page 257
Discussion

Add a beartrap warning that: You might need to adjust the field list depending on how your computer and ls command present the date. For example: you might need to add CRDAY=$7 and adjust CRTIME to $8 and FILE to $9.

Note from the Author or Editor:
Thanks to Mike Wong for this report

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 272
Lower half of page - multiple spaces delimit fields

The example only works correctly only if the "multiple spaces" are an even number of spaces.

If an odd number, the output contains both a tab and a space as field separators and must be further filtered to remove the extraneous space.

The extra space is the result of replacing 2 spaces with a tab. With an odd number of spaces, one space will always be left over.

Note from the Author or Editor:
Correct. The gsub should allow for an extra, optional space, like so: gsub (/\t+ ?/, "\t")

So both awk lines near the bottom (normal and hexdump) should have
BAD: gsub (/\t+/, "\t")
replaced by
GOOD: gsub (/\t+ ?/, "\t")

Looks like: awk 'BEGIN { FS = " "; OFS = "\t" } { $1 = $1; gsub (/\t+ ?/, "\t"); print }' data_file1 ( | hexdump -C)

Maine_guy  Sep 18, 2012  Nov 15, 2013
Printed
Page 288
twice at top of page

There are two "$#182;" entities that should be the paragraph symbol.

And IIRC that symbol was used in other places in the book as well.

Note from the Author or Editor:
Replace "$#182;" with the paragraph symbol here and anywhere else it's wrong.

JP Vossen
JP Vossen
 
Feb 28, 2009  Nov 15, 2013
Printed
Page 293
Above Discussion

Add beartrap: $RANDOM is not supported in dash (e.g., used in Ubuntu 6.06+), see also recipe 15.3.

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 296
See also

Add x-ref to recipe 15.3

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 298
mid page

$ find some_directory -type f | xargs chmod 0644 # File perms
$ find some_directory -type d | xargs chmod 0755 # Dir. perms

should use -print0 and -0

Note from the Author or Editor:
Change to:

$ find some_directory -type f -print0 | xargs -0 chmod 0644 # File perms
$ find some_directory -type d -print0 | xargs -0 chmod 0755 # Dir. perms

Also add a see also to recipe 9.2

JP Vossen
JP Vossen
 
Mar 07, 2009  Nov 15, 2013
Printed
Page 325
See also

Just above see also add a hint:

Debian/Ubuntu and Ubuntu users should install the 'devscripts' package (aptitude install devscripts) which provides a 'checkbashisms' script to help find "bashisms" that will not work in dash.

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Page 328 / 13.15
2nd & 3rd code snippets

The code snippet 2 & 3 in bold that trims white space using a simple pattern match doesn't actually do so.
while read; do echo "~~${REPLY## }~~"; done < whitespace
while read; do echo "~~${REPLY%% }~~"; done < whitespace

At its best, it will remove one space and leave the rest. So if you input the first snippet something like,
~~ This line has leading spaces.~~
It will print,
~~ This line has leading spaces.~~
Note, there are 2 leading spaces in input and 1 leading space in output.

Note from the Author or Editor:
Prod: Note, this errata says "bash Cookbook: Rough Cuts Version" but it is really "bash Cookbook 2nd edition" print, page 328 as noted. The repo is now updated, see 4667f09.

Wow, that's a great catch, thank you! It _seems_ to work using our `whitespace` file example, but you are correct, it does not.

To make it work, we need `shopt -s extglob` which we mention later but did not use here, and `+( )` to match one *or more* spaces.

Here's a more clear example:
```
# Make sure extended pattern matching operators are off (unset)
$ shopt -u extglob

# Fail: Leading SPACE only, original = removes only 1 space
$ while read; do echo "~~${REPLY## }~~"; done < <(echo -e "Zero leading\n One leading\n Two leading\n Three leading")
~~Zero leading~~
~~One leading~~
~~ Two leading~~
~~ Three leading~~

# Fail: Leading SPACE only, modified, requires: shopt -u extglob (which is not set)
$ while read; do echo "~~${REPLY##+( )}~~"; done < <(echo -e "Zero leading\n One leading\n Two leading\n Three leading")
~~Zero leading~~
~~ One leading~~
~~ Two leading~~
~~ Three leading~~


# Fail: Trailing SPACE only, original = removes only 1 space
$ while read; do echo "~~${REPLY%% }~~"; done < <(echo -e "Zero trailing\nOne trailing \nTwo trailing \nThree trailing ")
~~Zero trailing~~
~~One trailing~~
~~Two trailing ~~
~~Three trailing ~~

# Fail: Trailing SPACE only, modified, requires: shopt -u extglob (which is not set)
$ while read; do echo "~~${REPLY%%+( )}~~"; done < <(echo -e "Zero trailing\nOne trailing \nTwo trailing \nThree trailing ")
~~Zero trailing~~
~~One trailing ~~
~~Two trailing ~~
~~Three trailing ~~


# Enable extended pattern matching operators
$ shopt -s extglob

# Works: Leading SPACE only, modified, requires: shopt -u extglob
$ while read; do echo "~~${REPLY##+( )}~~"; done < <(echo -e "Zero leading\n One leading\n Two leading\n Three leading")
~~Zero leading~~
~~One leading~~
~~Two leading~~
~~Three leading~~

# Works: Trailing SPACE only, modified, requires: shopt -u extglob
$ while read; do echo "~~${REPLY%%+( )}~~"; done < <(echo -e "Zero trailing\nOne trailing \nTwo trailing \nThree trailing ")
~~Zero trailing~~
~~One trailing~~
~~Two trailing~~
~~Three trailing~~


# The originals will STILL FAIL to remove more than 1 space
$ while read; do echo "~~${REPLY## }~~"; done < <(echo -e "Zero leading\n One leading\n Two leading\n Three leading")
~~Zero leading~~
~~One leading~~
~~ Two leading~~
~~ Three leading~~

$ while read; do echo "~~${REPLY%% }~~"; done < <(echo -e "Zero trailing\nOne trailing \nTwo trailing \nThree trailing ")
~~Zero trailing~~
~~One trailing~~
~~Two trailing ~~
~~Three trailing ~~
```

saravana  Oct 02, 2024 
Printed
Page 344
Above See Also

Add a hint:

Per (http://www.gnu.org/software/coreutils/faq/coreutils-faq.html#Argument-list-too-long), Linux 2.6.23+ removes this limit, though it may still be reported; or it may not yet be removed in your particular distribution's kernel.

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 405
'diff' aliases near bottom

The diff aliases may conflict with each other and cause errors. Add a leading '\' to unalias the 'diff'.

Note from the Author or Editor:
Correct:
alias diff='\diff -u'
alias jdiff='\diff .........

JP Vossen
JP Vossen
 
May 23, 2009  Nov 15, 2013
Printed
Page 406
Line 10

In alias wgetdir line:
replace: --non-verbose
With: --no-verbose

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 419
Above Discussion

Add missing lines
Between "# Turn logging back off" and "screen -X log off"
add 2 lines:

screen -X logfile 1 # Set buffer to 1 sec
sleep 3 # Wait to avoid file truncation?

So it looks like:

# Turn logging back off
screen -X logfile 1 # Set buffer to 1 sec
sleep 3 # Wait to avoid file truncation?
screen -X log off

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 421
Script: archive_meta-data

Remove '\)' in last line of find, just above warning beartrap:

...\n' \) >> archive_file

becomes

...\n' >> archive_file

Note from the Author or Editor:
Thanks to Mike Wong for this report.

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 421
archive_meta-data

Remove unbalanced ')' in last line of solution code.

was:
-printf '%m %u %g %s %t %p
' ) >> archive_file
should be:
-printf '%m %u %g %s %t %p
' >> archive_file

Anonymous    Nov 15, 2013
Printed
Page 442
See Also

Add "man pgrep" to end of see also section.

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 445
Line 10 up from bottom

\$0 in wrong place:

current:
{ print \"$HOSTNAME\", \$0 }"

correct:
{ print \$0, \"$HOSTNAME\" }"

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 451
Solution

Add to bottom of solution:

Or you can try this sed solution from the sed FAQ (http://www.linuxtopia.org/online_books/linux_tool_guides/the_sed_faq/sedfaq4_007.html)

sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' /path/to/file

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 452
See Also

Add http://www.linuxtopia.org/online_books/linux_tool_guides/the_sed_faq/sedfaq4_007.html

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 457
2nd paragraph

The second paragraph says that it is not possible to do substitutions like s/-g -A/-gA/ in !!, because substitutions are applied successively to each word. However this is not true, such substitution works well in bash, at least in versions 2.05b and 3.2. Also in bashref it is said that ^string1^string2^ and !!:s/string1/string2/ mechanisms are equivalent.

Note from the Author or Editor:
Delete the entire first full paragraph of p. 457, the one that begins "The comparison with sed..." and ends "...words to bash."

Rename 18.4 as Simpler Substituting Syntax
Change the paragraph under "Problem" to read:
Here's a simpler syntax for making substitutions in your previously-executed command and running the modified result.

Anonymous  Aug 23, 2008  Nov 15, 2013
Printed
Page 472
Last code block

The code block just repeats the problem that you describe at the end of the 'Problem' section at the start of 19.8. The value of COUNT will always be zero.

Something like this would retain the value of COUNT in the main program:

COUNT=0
COUNT=`cat $1 |
(
while read PREFIX GUTS
do
# ...
if [[ $PREFIX == "abc" ]] #
then
let COUNT++
fi
# ...
done
echo $COUNT
)`

Note from the Author or Editor:
The bottom example on page 471 works for me (JP), but I think I may see the submitter's problem. All of the examples **in the Discussion** section simply echo the value of COUNT. So if you want to actually use that value for something in the main script, you need to capture it into a variable that the main program can see.

However, the method we presented in the Solution section does not have that problem; it does place the value of $COUNT back into the main script. (Actually, it never uses a pipeline, so it side-steps the whole problem. Which is the point.) But the difference is very small and hard to see. [1]

An alternate way to get the data back to the main script using a "| read COUNT" is shown at the bottom of page 472, but requires a sub-shell.

The submitter's solution also worked for me, and did get the value back into the main script, but it is inefficient since it creates 2 sub-shells due to use of both `` and (). That solution could eliminate the () and simply place our "done < $1" method (from the SOLUTION section) into a COUNT=`...` statement, but that's not needed.

Using our actual solution doesn't require the `` either, since as noted above it side-steps the whole problem by using the "done < $1" line and keeps the value of $COUNT in the main script. I think the submitted missed that point, which means we need to make it more clear.

_______________________
[1] We probably need to spell out the examples and specifically call out the important change in the solution. Proposed fix:

19.8
PROBLEM

You have a script that works just fine, reading input in a while loop:

# This works as expected
COUNT=0
while read PREFIX GUTS
do
# ...
if [[ $PREFIX == "abc" ]]
then
let COUNT++
fi
# ...
done
echo $COUNT

and then you change it to read from a file:

# Don't use: this does NOT work as expected!
COUNT=0
cat $1 | while read PREFIX GUTS
do
# ...
if [[ $PREFIX == "abc" ]]
then
let COUNT++
fi
# ...
done
echo $COUNT # $COUNT is always '0' which is broken

only now it no longer works...$COUNT keeps coming out as zero.


Solution
[... same]

# Avoid the | and sub-shell; use "done < $1" instead
# It now works as expected
COUNT=0
while read PREFIX GUTS
do
# ...
if [[ $PREFIX == "abc" ]]
then
let COUNT++
fi
# ...
done < $1 # <<<< This is the key line
echo "$COUNT now lives in the main script"

Anonymous  Jan 09, 2009  Nov 15, 2013
Printed
Page 472 Polish Edition
Recipe 17.14

Hi
Bad ed script:
----cut----
1
i
Header 1
Header 2
.
w
q
----end----

This should by:
----cut----
1i
Header 1
Header 2
.
w
q
----end----

and next:
ed -s file <ed_script

Explanation:
1 in first line is alias 1p (default commant - print)

Option -s turn off only diagnostic data.

Best
sjd
(lover of ed editor :-)


Note from the Author or Editor:
Nice catch! I learned something new, thanks.

My script does work, but not quite the way I thought it did. The corrected script is better and more accurate.


REPLACE top of ed script as follows:
---- begin cut here ----
$ cat ed_script
1
i
---- end cut here ----

WITH:
---- begin cut here ----
$ cat ed_script
1i
---- end cut here ----


REPLACE entire para beginning:
---- begin cut here ----
The 1 in the ed script means to...
---- end cut here ----

WITH:
---- begin cut here ----
The 1p in the ed script means to go to the first line and then go into insert mode, and the next two lines are literal. A single . all by itself on a line exits insert mode, w writes the file and q quits. The -s suppresses diagnostic output specifically for use in scripts.
---- end cut here ----

Slawomir Dziuba  Jan 30, 2010  Nov 15, 2013
Printed
Page 507
Row 12 of table

Missing leading 'n' in:

>> file Direct file descriptor n to file; append...


correct:

n>> file Direct file descriptor n to file; append...

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 507
line 14

The line beginning ">> file" should begin "n>> file".

From the author:

What I am trying to show in the examples is expansion
of revision meta-data (keywords), so the first instance is literal:
# $Id$
while the second instance is support to be expanded, e.g.:
# $Id: hello,v 1.4 2006/07/21 08:57:53 jp Exp $

Something happened to my $Id$ lines. Between the Aardvark issues and my
other revision control stuff, it probably just got nuked by a revision
control system itself. But they are broken. Here is what they should
be, but the chapter is otherwise OK.

It is supposed to show the addition of they keyword $Id$, then last in
the example the expansion of that keyword. The example examples got nuked.

App D pages:

Anonymous    Nov 15, 2013
PDF
Page 507
After entry for 'Here Document'

Table A-10, I/O redirection, is missing an entry for the 'Here strings' operator, <<<, which is referenced at various other points in the book.

Note from the Author or Editor:
Confirmed. After "<< label Here-document." add:
<<< word Here-string.

radomire  Dec 24, 2012  Nov 15, 2013
Printed
Page 512
5th comment in A-17

Missing 'e' in not in second line of 5th comment in table A-17

Wrong:
... not reuse ...

correct:
... note reuse ...

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 515
Top chart

Alignment of classes off, extra space between [[:alpha:]] and [[:ascii:]]
Remove space to line up

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 540
Example

2 issues

1) End of first sent. in Example, add ?of this appendix?, as in:

...section in the Preface of this appendix.


2) Just below mid page, add '-m' to mkdir line:

/tmp$ mkdir -m 0700 scripts

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 540
"Create a new project and import it"

/tmp$ mkdir 0700 scripts
missing '-m', should be:
/tmp$ mkdir -m 0700 scripts

Anonymous    Nov 15, 2013
Printed
Page 540 and 546
end of 1st sent. add for clarity

This example is not suitable for enterprise or multiuser access (see the "More Resources" section in the
Preface [for clarity add: "of this appendix").

This is in 2 places and is more broken than I thought. The references are in the "See Also" parts of
section, as I originally noted. I'm not sure where the "More Resources" or Preface stuff came from, but
they are wrong.

Anonymous    Nov 15, 2013
Printed
Page 543
Example at bottom

3 problems with example output/display at bottom.

1) First $Id$ is missing leading '#'
2) cvs ci -m line missing leading "* " in log message
3) Second "# $id$" not expanded correctly

Corrected fragment:

/home/jp/scripts$ cat hello
#!/bin/sh
# $Id$
echo 'Hello World!'
echo 'Hi Mom...'

/home/jp/scripts$ cvs ci -m'* Added ID keyword' hello
/home/jp/cvsroot/scripts/hello,v <-- hello
new revision: 1.4; previous revision: 1.3

/home/jp/scripts$ cat hello
#!/bin/sh
# $Id: hello,v 1.4 2006/07/21 08:57:53 jp Exp $

[...]

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 543
example at bottom, 3 issues [1].

/home/jp/scripts$ cat hello
#!/bin/sh
$Id$
missing '#' should be:
# $Id$

Trivial (missing '*'):
/home/jp/scripts$ cvs ci -m'Added ID keyword' hello
/home/jp/scripts$ cvs ci -m'* Added ID keyword' hello

/home/jp/scripts$ cat hello
#!/bin/sh
# $Id$
should be:
# $Id: hello,v 1.4 2006/07/21 08:57:53 jp Exp $

Anonymous    Nov 15, 2013
Printed
Page 544
Above See Also

Final "# $Id$" not expanded, should be:

/home/jp/cvs.scripts$ cat hello
#!/bin/sh
# $Id: hello,v 1.4 2006/07/21 08:57:53 jp Exp $
echo 'Hello World!'
echo 'Hi Mom...'

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 544
above "See Also"

/home/jp/scripts$ cat hello
#!/bin/sh
# $Id$
should be:
# $Id: hello,v 1.4 2006/07/21 08:57:53 jp Exp $

Anonymous    Nov 15, 2013
Printed
Page 545

/home/jp/bin$ cat hello
#!/bin/sh
# $Id$
should be [1]:
# $Id: hello,v 1.4 2006/07/21 09:18:09 jp Exp $

Anonymous    Nov 15, 2013
Printed
Page 546
Example

End of first sent. in Example, add ?of this appendix?, as in: ...section in the Preface of this appendix.

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 546
end of 1st sent. add for clarity

This example is not suitable for enterprise or multiuser access (see the "More Resources" section in the
Preface [for clarity add: "of this appendix").

Anonymous    Nov 15, 2013
Printed
Page 549
Middle example

4 problems

1) First prompt missing "/trunk" in path
2) Second prompt missing "/trunk" in path
3) svn ci -m line missing leading "* " in log message
4) Final "# $id$" not expanded correctly

Corrected example:

/home/jp/scripts/trunk$ vi hello

/home/jp/scripts/trunk$ cat hello
#!/bin/sh
# $Id$
echo 'Hello World!'
echo 'Hi Mom...'

home/jp/scripts/trunk$ svn propset svn:keywords "Id" hello
property 'svn:keywords' set on 'hello'

/home/jp/scripts/trunk$ svn ci -m'* Added ID keyword' hello
Sending hello

Committed revision 4.

/home/jp/scripts/trunk$ cat hello
#!/bin/sh
# $Id: hello 5 2006-07-21 09:09:34Z jp $
echo 'Hello World!'
echo 'Hi Mom...'

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 549
4 issues in the example in the middle of the page

Cosmetic:
/home/jp/scripts$ vi hello
/home/jp/scripts$ cat hello
should have "/trunk"
/home/jp/scripts/trunk$ vi hello
/home/jp/scripts/trunk$ cat hello

Trivial (missing '*'):
/home/jp/scripts/trunk$ svn ci -m'Added ID keyword' hello
/home/jp/scripts/trunk$ svn ci -m'* Added ID keyword' hello

(Note, first instance of "# $Id$" is correct as-is.)

/home/jp/scripts/trunk$ cat hello
#!/bin/sh
# $Id$
should be [1]:
# $Id: hello 5 2006-07-21 09:09:34Z jp $

Anonymous    Nov 15, 2013
Printed
Page 550
Above See Also

"# $id$" just above See Also is not expanded. Should be:

# $Id: hello 5 2006-07-21 09:09:34Z jp $

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 550

/home/jp/scripts/trunk$ cat hello
#!/bin/sh
# $Id$
should be [1]:
# $Id: hello 5 2006-07-21 09:09:34Z jp $

Anonymous    Nov 15, 2013
Printed
Page 554
Near mid page

"# $Id$" is not expanded, should be:

# $Id: hello,v 1.4 2006/07/21 09:18:09 jp Exp $


As in:

/home/jp/bin$ cat hello
#!/bin/sh
# $Id: hello,v 1.4 2006/07/21 09:18:09 jp Exp $
echo 'Hello World!'
echo 'Hi Mom...'

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 554
just above "Compare the current revision to r1.2"

(Note, first instance of "# $Id$" is correct as-is.)

/home/jp/bin$ cat hello
#!/bin/sh
# $Id$
should be [1]:
# $Id: hello,v 1.4 2006/07/21 09:18:09 jp Exp $

580, 3rd line up from bottom,
581, 3rd line up from see also
# $Id: hello,v 1.4 2006/07/21 08:57:53 jp Exp $

586, 17th line up from bottom, more or less
587, 3rd line up from see also
# $Id: hello 5 2006-07-21 09:09:34Z jp $

591, 22nd or so line up from bottom
592, 2nd line from top
# $Id: hello,v 1.4 2006/07/21 09:18:09 jp Exp $

594, 3rd line of 2nd para in Document Comparison, remove "in Chapter 12"
for consistency with the rest of the xrefs in the book.

Anonymous    Nov 15, 2013
Printed
Page 555
Example at top

"# $Id$" is not expanded, should be:

# $Id: hello,v 1.4 2006/07/21 09:18:09 jp Exp $

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 570
Missing index entry

Bottom (bot), 383

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 571
Missing index entry

CDPATH, 367

(and others?)

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 579
Missing index entry

Grouping using {}, 42


(and/or see also '{} braces' on page 568)

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 579
Missing index entry

Grouping using () 42

(and/or see also ()...)

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 580
Missing index entry

$IFS, 281

[Maybe other uses?]

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 586
Missing index entry

$RANDOM, 292

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 586
Missing index page ref

Add 342 to:

redirection operators, 38, 342

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 586
read statement index entry

'read' is used on page 470, so that page number should be added to the index entry

JP Vossen
JP Vossen
 
Feb 06, 2009  Nov 15, 2013
Printed
Page 587
Missing index entry

script (command), 419

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 592
Missing index page refs

Missing 432, 451, other?

sed 277, 431, 451

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013
Printed
Page 594
Missing index entry

sum, 158

JP Vossen
JP Vossen
 
Dec 30, 2008  Nov 15, 2013