This commit is contained in:
gferg 2005-10-21 13:31:28 +00:00
parent 5fc56c0188
commit b1fa399900
11 changed files with 765 additions and 217 deletions

View File

@ -6,6 +6,91 @@
http://personal.riverusers.com/~thegrendel/Change.log
------------------------------------------------------------------------
Version 3.7
Whortleberry release, 10/23/05
1) In "Special Characters" chapter:
At "whitespace" entry, added footnote about newline/linefeed.
2) In "Basic Commands" section of "External Commands" Chapter:
At "ln" entry, noted that only symbolic links can refer to a directory.
3) In "Text Processing Commands" section of "External Commands" Chapter:
Modified comments in "wf.sh" example.
At "grep" entry, fixed 2 typos
"Now, let's search this file . . . "
"printf 'a b\nc d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz ."
At "diff" entry, fixed typo ("spiff" --> "sdiff").
(Thank you, Frank Wang.)
At "colrm" entry, changed "warning" to "caution" -- toned it down a bit.
At "cut" entry,
Added note about using linefeed as delimiter.
(Thank you, Jaka Kranjc.)
Got rid of unnecessary "cat" in inline example.
At "iconv" entry, added snippet of code from "booklistgen.sh" script.
(Thank you, Peter Knowles, for permission to use it.)
4) In "Complex Commands" section of "External Commands" Chapter:
At "expr" entry, added usage example of escaped parentheses.
(Thank you, Peter Knowles, for permission to use it.)
5) In "File and Archiving Commands" section of "External Commands" Chapter:
Added "sha1sum" command at Frank Wang's suggestion.
6) In "Communications Commands" section of "External Commands" chapter:
In "Remote Host Access" subsection, added "scp" entry.
Added material at "uucp" entry.
Added "uux" entry.
At "wget" listing, added comments.
At "rsync" entry, fixed up usage example.
Added "fc4upd.sh" example.
(Thank you, Frank Wang.)
7) In "Complex Commands" section of "External Commands" Chapter:
At "xargs" entry, added footnote about speeding up execution.
8) In "Math Commands" section of "External Commands" chapter:
Added Frank Wang's comments to "monthlypmt.sh" example.
9) In "Miscellaneous Commands" section of "External Commands" chapter:
At "tee" entry, redesigned diagram for greater clarity.
10) In "Testing and Branching" section of "Loops and Branches" chapter:
Rewrote explanation of filename "globbing" in the [list] of a for-loop
and added comments to "list-glob.sh" example.
11) In "Quoting" chapter:
Added sidebar near beginning of chapter.
Removed intro paragraph (superfluous) at beginning of "Quoting Variables"
section.
12) In "$RANDOM" section of "Variables Revisited" chapter:
Added comment to "ex21.sh" example.
13) In "Command Substitution" chapter:
Added footnote about nesting command substitution with backticks
by using escaping.
(Thanks, John Default.)
14) In "System and Administrative Commands" chapter:
Moved "dmesg" entry to "Information and Statistics" subsection.
In "Process Control and Booting" subsection, added "service" entry.
At "uptime" entry, added note about load average.
Fixups at "terminals and modes" sidebar, second example.
(Thank you, Mark Norman.)
15) In "Bibliography" section:
Added reference and URL for Col Needham's original IBDB scripts.
16) Numerous typos corrected, per a list sent in by Mark Norman (thanks!).
17) Various changes and fixups in example scripts.
Version 3.6
Pokeberry release, 08/28/05
@ -75,13 +160,10 @@ Pokeberry release, 08/28/05
At "xargs" entry, added extra usage example.
At "expr" entry, added example of illegal arithmetic operation.
14) In "Here Documents" chapter:
Added "self-document2.sh" example.
15) In "$RANDOM" section of "Variables Revisited" chapter:
14) In "$RANDOM" section of "Variables Revisited" chapter:
Added Frank Wang's alternative to jipe's example.
16) In "Quoting" chapter:
15) In "Quoting" chapter:
Split the chapter into introduction and "Quoting Variables" and
"Escaping" sections.
@ -93,33 +175,33 @@ Pokeberry release, 08/28/05
splitting.
(Thank you, Harald Koenig.)
17) In "Local Variables" section of "Functions" chapter:
16) In "Local Variables" section of "Functions" chapter:
In footnoted example of a segfaulting recursive function,
added an "echo" to properly exercise the function.
(Thank you, Dr. Roland Sonnenschein.)
18) In "Debugging" chapter:
17) In "Debugging" chapter:
At listing of "Tools for debugging non-working scripts,"
added list item for "$LINENO" variable and "caller" builtin.
At "trap" entry, replaced buggy "multiple-processes.sh" example.
(Thank you, Tedman Eng.)
19) In "Copyright" chapter:
18) In "Copyright" chapter:
Updated licensing terms to give the LDP the right to reassign custodianship
of the book in the event the author cannot be contacted.
20) In "Bibliography" section:
19) In "Bibliography" section:
Added entry for Peter Knowles' booklistgen.sh --
Sony Librie booklist generator -- making possible
Linux access to this neat e-book reader.
21) Corrected spelling of the name of contributor Stéphane Chazelas
20) Corrected spelling of the name of contributor Stéphane Chazelas
in multiple places.
(Thank you, Bertrand Mollinier Toublet, for pointing out these
embarrassing typos.)
22) Various changes and fixups in example scripts.
21) Various changes and fixups in example scripts.

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,8 @@ echo "Random number less than $RANGE --- $number"
echo
# If you need a random integer greater than a lower bound,
#+ then set up a test to discard all numbers below that.
@ -44,6 +46,12 @@ done
echo "Random number greater than $FLOOR --- $number"
echo
# Let's examine a simple alternative to the above loop, namely
# let "number = $RANDOM + $FLOOR"
# That would eliminate the while-loop and run faster.
# But, there might be a problem with that. What is it?
# Combine above two techniques to retrieve random number between two limits.
number=0 #initialize

View File

@ -0,0 +1,214 @@
#!/bin/bash
# fc4upd.sh
# Script author: Frank Wang.
# Slight stylistic modifications by ABS Guide author.
# Used in ABS Guide with permission.
# Download Fedora 4 update from mirror site using rsync.
# Only download latest package if multiple versions exist,
#+ to save space.
URL=rsync://distro.ibiblio.org/fedora-linux-core/updates/
# URL=rsync://ftp.kddilabs.jp/fedora/core/updates/
# URL=rsync://rsync.planetmirror.com/fedora-linux-core/updates/
DEST=${1:-/var/www/html/fedora/updates/}
LOG=/tmp/repo-update-$(/bin/date +%Y-%m-%d).txt
PID_FILE=/var/run/${0##*/}.pid
E_RETURN=65 # Something unexpected happened.
# General rsync options
# -r: recursive download
# -t: reserve time
# -v: verbose
OPTS="-rtv --delete-excluded --delete-after --partial"
# rsync include pattern
# Leading slash causes absolute path name match.
INCLUDE=(
"/4/i386/kde-i18n-Chinese*"
# ^ ^
# Quoting is necessary to prevent globbing.
)
# rsync exclude pattern
# Temporarily comment out unwanted pkgs using "#" . . .
EXCLUDE=(
/1
/2
/3
/testing
/4/SRPMS
/4/ppc
/4/x86_64
/4/i386/debug
"/4/i386/kde-i18n-*"
"/4/i386/openoffice.org-langpack-*"
"/4/i386/*i586.rpm"
"/4/i386/GFS-*"
"/4/i386/cman-*"
"/4/i386/dlm-*"
"/4/i386/gnbd-*"
"/4/i386/kernel-smp*"
# "/4/i386/kernel-xen*"
# "/4/i386/xen-*"
)
init () {
# Let pipe command return possible rsync error, e.g., stalled network.
set -o pipefail
TMP=${TMPDIR:-/tmp}/${0##*/}.$$ # Store refined download list.
trap "{
rm -f $TMP 2>/dev/null
}" EXIT # Clear temporary file on exit.
}
check_pid () {
# Check if process exists.
if [ -s "$PID_FILE" ]; then
echo "PID file exists. Checking ..."
PID=$(/bin/egrep -o "^[[:digit:]]+" $PID_FILE)
if /bin/ps --pid $PID &>/dev/null; then
echo "Process $PID found. ${0##*/} seems to be running!"
/usr/bin/logger -t ${0##*/} \
"Process $PID found. ${0##*/} seems to be running!"
exit $E_RETURN
fi
echo "Process $PID not found. Start new process . . ."
fi
}
# Set overall file update range starting from root or $URL,
#+ according to above patterns.
set_range () {
include=
exclude=
for p in "${INCLUDE[@]}"; do
include="$include --include \"$p\""
done
for p in "${EXCLUDE[@]}"; do
exclude="$exclude --exclude \"$p\""
done
}
# Retrieve and refine rsync update list.
get_list () {
echo $$ > $PID_FILE || {
echo "Can't write to pid file $PID_FILE"
exit $E_RETURN
}
echo -n "Retrieving and refining update list . . ."
# Retrieve list -- 'eval' is needed to run rsync as a single command.
# $3 and $4 is the date and time of file creation.
# $5 is the full package name.
previous=
pre_file=
pre_date=0
eval /bin/nice /usr/bin/rsync \
-r $include $exclude $URL | \
egrep '^dr.x|^-r' | \
awk '{print $3, $4, $5}' | \
sort -k3 | \
{ while read line; do
# Get seconds since epoch, to filter out obsolete pkgs.
cur_date=$(date -d "$(echo $line | awk '{print $1, $2}')" +%s)
# echo $cur_date
# Get file name.
cur_file=$(echo $line | awk '{print $3}')
# echo $cur_file
# Get rpm pkg name from file name, if possible.
if [[ $cur_file == *rpm ]]; then
pkg_name=$(echo $cur_file | sed -r -e \
's/(^([^_-]+[_-])+)[[:digit:]]+\..*[_-].*$/\1/')
else
pkg_name=
fi
# echo $pkg_name
if [ -z "$pkg_name" ]; then # If not a rpm file,
echo $cur_file >> $TMP #+ then append to download list.
elif [ "$pkg_name" != "$previous" ]; then # A new pkg found.
echo $pre_file >> $TMP # Output latest file.
previous=$pkg_name # Save current.
pre_date=$cur_date
pre_file=$cur_file
elif [ "$cur_date" -gt "$pre_date" ]; then # If same pkg, but newer,
pre_date=$cur_date #+ then update latest pointer.
pre_file=$cur_file
fi
done
echo $pre_file >> $TMP # TMP contains ALL
#+ of refined list now.
# echo "subshell=$BASH_SUBSHELL"
} # Bracket required here to let final "echo $pre_file >> $TMP"
# Remained in the same subshell ( 1 ) with the entire loop.
RET=$? # Get return code of the pipe command.
[ "$RET" -ne 0 ] && {
echo "List retrieving failed with code $RET"
exit $E_RETURN
}
echo "done"; echo
}
# Real rsync download part.
get_file () {
echo "Downloading..."
/bin/nice /usr/bin/rsync \
$OPTS \
--filter "merge,+/ $TMP" \
--exclude '*' \
$URL $DEST \
| /usr/bin/tee $LOG
RET=$?
# --filter merge,+/ is crucial for the intention.
# + modifier means include and / means absolute path.
# Then sorted list in $TMP will contain ascending dir name and
#+ prevent the following --exclude '*' from "shortcutting the circuit."
echo "Done"
rm -f $PID_FILE 2>/dev/null
return $RET
}
# -------
# Main
init
check_pid
set_range
get_list
get_file
RET=$?
# -------
if [ "$RET" -eq 0 ]; then
/usr/bin/logger -t ${0##*/} "Fedora update mirrored successfully."
else
/usr/bin/logger -t ${0##*/} "Fedora update mirrored with failure code: $RET"
fi
exit $RET

View File

@ -32,14 +32,13 @@ fi
gcd ()
{
# Arbitrary assignment.
dividend=$1 # It does not matter
divisor=$2 #+ which of the two is larger.
# Why?
dividend=$1 # Arbitrary assignment.
divisor=$2 #+ It doesn't matter which of the two is larger.
# Why not?
remainder=1 # If uninitialized variable used in loop,
#+ it results in an error message
#+ on first pass through loop.
#+ on the first pass through loop.
until [ "$remainder" -eq 0 ]
do

View File

@ -23,9 +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.
# ----------------------------------------------------------------------
# -----------------------------------------------------------------------
# Every file has an inode, a record that holds 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.

View File

@ -1,18 +1,20 @@
#!/bin/bash
# list-glob.sh: Generating [list] in a for-loop using "globbing".
# list-glob.sh: Generating [list] in a for-loop, using "globbing"
echo
for file in *
# ^ Bash performs filename expansion
#+ on expressions that globbing recognizes.
do
ls -l "$file" # Lists all files in $PWD (current directory).
# Recall that the wild card character "*" matches every filename,
# however, in "globbing", it doesn't match dot-files.
# Recall that the wild card character "*" matches every filename,
#+ however, in "globbing," it doesn't match dot-files.
# If the pattern matches no file, it is expanded to itself.
# To prevent this, set the nullglob option
# (shopt -s nullglob).
# Thanks, S.C.
# If the pattern matches no file, it is expanded to itself.
# To prevent this, set the nullglob option
#+ (shopt -s nullglob).
# Thanks, S.C.
done
echo; echo

View File

@ -40,6 +40,8 @@ read term
bottom=$(echo "scale=9; $bottom+$bot" | bc)
# bottom = $(($bottom + $bot"))
done
# ====================================================================
# --------------------------------------------------------------------
# Rick Boivie pointed out a more efficient implementation
#+ of the above loop, which decreases computation time by 2/3.
@ -61,8 +63,18 @@ read term
# done
# echo 'bottom'
# } | bc` # Embeds a 'for loop' within command substitution.
# --------------------------------------------------------------------------
# On the other hand, Frank Wang suggests:
# bottom=$(echo "scale=9; ($interest_rate^$term-1)/($interest_rate-1)" | bc)
# Because . . .
# The algorithm behind the loop
#+ is actually a sum of geometric proportion series.
# The sum formula is e0(1-q^n)/(1-q),
#+ where e0 is the first element and q=e(n+1)/e(n)
#+ and n is the number of elements.
# --------------------------------------------------------------------------
# ====================================================================
# let "payment = $top/$bottom"
payment=$(echo "scale=2; $top/$bottom" | bc)
@ -75,6 +87,7 @@ read term
exit 0
# Exercises:
# 1) Filter input to permit commas in principal amount.
# 2) Filter input to permit interest to be entered as percent or decimal.

View File

@ -69,8 +69,15 @@ exit 0
# I ran it with limit = 500 and after the first few hundred iterations,
#+ one of the concurrent threads disappeared!
# Not sure if this is collisions from trap signals or something else.
# Once the trap is received, there's a brief moment while executing the
#+ trap handler but before the next trap is set. During this time, it may
#+ be possible to miss a trap signal, thus miss spawning a child process.
# No doubt someone may spot the bug and will be writing
#+ . . . in the future.
# ===================================================================== #

View File

@ -34,7 +34,7 @@ while read name passwd uid gid fullname ignore
do
echo "$name ($fullname)"
done </etc/passwd # I/O redirection.
IFS=$OIFS # Restore originial $IFS.
IFS=$OIFS # Restore original $IFS.
# This code snippet also by Heiner Steven.

View File

@ -43,6 +43,11 @@ sed -e 's/\.//g' -e 's/\,//g' -e 's/ /\
#+ least significant column
#+ (word or string, optionally case-insensitive)
#+ and last on the most significant column (frequency)."
#
# As Frank Wang explains, the above is equivalent to
#+ . . . | sort | uniq -c | sort +0 -nr
#+ and the following also works:
#+ . . . | sort | uniq -c | sort -k1nr -k
########################################################
exit 0