mirror of https://github.com/tLDP/LDP
updated
This commit is contained in:
parent
1d623d704e
commit
112d2a3d5c
|
@ -2,7 +2,183 @@ RELEASE HISTORY
|
|||
------- -------
|
||||
Change log
|
||||
|
||||
Version 1.0.X interim release
|
||||
|
||||
Version 1.2
|
||||
03/31/02
|
||||
|
||||
1) In "Operators" subsection of "Operations and Related Topics" chapter:
|
||||
Fixed comment in in-line example (thanks, Marcus Bergöf).
|
||||
Added "gcd.sh" example at "%" (modulo) operator.
|
||||
|
||||
2) In "Numerical Constants" subsection of "Operations and Related Topics"
|
||||
chapter:
|
||||
Fixed up and enhanced "numbers.sh" example (thanks, Rich Bartell).
|
||||
|
||||
3) In "arithops.sh" example, fixed comment to refer to correct operation
|
||||
(thanks, Marcus Bergöf).
|
||||
|
||||
4) In "Command Substitution" chapter:
|
||||
Added excerpts from /etc/rc.d/rc.sysinit as examples of setting
|
||||
a variable to the contents of a file using "var=`cat filename`
|
||||
construction.
|
||||
Added "csubloop.sh" example of setting a variable from the output of a
|
||||
loop.
|
||||
|
||||
5) In "Basic Commands" section of "External Commands and Filters" chapter:
|
||||
Added info on "-f" option at "mv" and "rm".
|
||||
Added "-s" option at "cat".
|
||||
|
||||
6) In "Text Processing Commands" sect. of "External Commands and Filters" chapt.:
|
||||
Added more info for "nl".
|
||||
Rewrote "groff" as a separate entry, and added "col" and "tbl"/"eqn"
|
||||
as subentries.
|
||||
Added much more info on "tr".
|
||||
Added more options to "grep".
|
||||
|
||||
7) In "Complex Commands" section of "External Commands" chapter:
|
||||
Added more info at "xargs".
|
||||
Added caution when using "*" with "expr" in arithmetic operation.
|
||||
|
||||
8) In "Miscellaneous Commands" section of "External Commands" chapter:
|
||||
Added more info on "jot/seq".
|
||||
Added "Linux Journal" reference at "m4".
|
||||
|
||||
9) In "File and Archiving Commands" section of "External Commands and Filters"
|
||||
chapter:
|
||||
Added "mimencode/mmencode".
|
||||
More info on "cksum"/"md5sum".
|
||||
Added "wstrings.sh" example at "strings" entry.
|
||||
|
||||
10) In "Communications Commands" section of "External Commands" chapter:
|
||||
Added "mail", with "self-mailer.sh" illustrative example.
|
||||
|
||||
11) In "Time/Date Commands" section of "External Commands" chapter:
|
||||
Added discussion of "-u" option to "date".
|
||||
|
||||
12) In "Special Variable Types" section of "Introduction to Variables" chapter:
|
||||
Improved link to "bracket" notation.
|
||||
Added note that "shift" command also applies to function parameters.
|
||||
|
||||
13) In "Internal Variables" section of "Variables Revisited" chapter:
|
||||
Added info on "$@" special variable, with new in-line example.
|
||||
Corrected "$DIRSTACK" listing (thanks again, Nick Drage).
|
||||
At "$TMOUT", added "t-out.sh", another example of timed input (thanks,
|
||||
syngin seven).
|
||||
Added commentary to "am-i-root.sh" example.
|
||||
|
||||
14) Changed document subtitle.
|
||||
|
||||
15) In "Command Substitution" chapter:
|
||||
Corrected word-splitting example in "caution" (thanks, Tony Richardson).
|
||||
Added "stupid-script-tricks.sh" example of setting a variable to the
|
||||
contents of a binary file (which has no useful applications).
|
||||
|
||||
16) In "Internal Commands and Builtins" chapter:
|
||||
Clarified "ex43.sh" example (thanks, Tony Richardson).
|
||||
Clarified explanation and example of "echo" eating linefeeds in a
|
||||
command fed to it.
|
||||
More info on "keywords" topic.
|
||||
|
||||
17) In "Special Characters" chapter:
|
||||
Added in-line example of embedding Ctl-H's in a variable.
|
||||
More info on '-' as an option to certain commands.
|
||||
Added "background-loop.sh" example at "&" (run command in background).
|
||||
|
||||
18) In "Bash, version 2" chapter:
|
||||
Added "resistor-inventory.sh" example of database using indirect variable
|
||||
referencing.
|
||||
|
||||
19) Changed name of example "rot13_2.sh" to "rot14.sh" because otherwise SGML
|
||||
conversion seems to experience namespace confusion.
|
||||
|
||||
20) In "Quoting" chapter:
|
||||
Added header notes to "\" escape usage listing.
|
||||
Added in-line example on behavior of "\".
|
||||
Slight revisions to "escaped.sh" example.
|
||||
|
||||
21) In "Internal Variables" section of "Variables Revisited" Chapter:
|
||||
Added usage example for "$GROUPS".
|
||||
|
||||
22) In "Gotchas" chapter:
|
||||
Added mixing up integer and string comparison operators.
|
||||
|
||||
23) In "While Loops" subsection of "Loops and Branches" chapter:
|
||||
Added clarifying statement as to when "while loops" are used.
|
||||
Added "userlist.sh" example of command substitution in generating
|
||||
"[list]" in "for loop".
|
||||
|
||||
24) In "System and Administrative Commands" chapter:
|
||||
Added "rmmod".
|
||||
added "sudo".
|
||||
Added commentary on "debugfs".
|
||||
|
||||
25) In "Exercises" Appendix:
|
||||
Reorganization into two distinct subsections.
|
||||
Added a sample script to annotate.
|
||||
Added a script code snippet to fix up.
|
||||
Added a few more script writing problems, including the very difficult
|
||||
"Playfair Cipher".
|
||||
|
||||
26) Simplified "wf.sh" example.
|
||||
|
||||
27) In "Starting off with a Sha-Bang" chapter:
|
||||
Fixed typo in "ex2.sh" example script (thanks, David Kimbro for
|
||||
bringing this to my attention).
|
||||
|
||||
28) In "Arrays" chapter:
|
||||
Rewrote confusing language in introductory paragraph.
|
||||
Added "stackex.sh" example for emulating data structures.
|
||||
Added in-line example of loading an array with the contents of a text
|
||||
file.
|
||||
|
||||
29) In "Tests" chapter:
|
||||
Clarification of why semicolon needed when "if" and "then" are on same
|
||||
line.
|
||||
Added material to "ex10.sh" example.
|
||||
|
||||
30) In "Here Documents" chapter:
|
||||
Modified "ex69.sh" example, per message from Jess Thrysoee relaying to me
|
||||
clarification from Bram Moolenaar.
|
||||
|
||||
31) In "I/O Redirection" chapter:
|
||||
Fixed comment on in-line example on closing file descriptors.
|
||||
(Thanks, Matthieu Lucotte)
|
||||
Made the data file for redirection examples, "names.data", visible.
|
||||
|
||||
32) In "Assorted Tips" section of "Miscellany" chapter:
|
||||
Added repeated piping of the output of a filter back to that same filter.
|
||||
Added alternative method of having a function return a value to the body
|
||||
of the script, with "multiplication.sh" example showing how.
|
||||
Added method of having a function "return" multiple values,
|
||||
with illustrative "sum-product.sh" example.
|
||||
Added "tolower()" function to function library.
|
||||
Added methods of passing an array to a function, and returning an array
|
||||
from a function to the main body of a script (with example
|
||||
"array-function.sh").
|
||||
|
||||
33) In "Contributed Scripts" appendix:
|
||||
Added "collatz.sh" example.
|
||||
Added "life.sh" example (Conway's "Game of Life").
|
||||
|
||||
34) In "Exit Codes" appendix:
|
||||
Added footnote with more information about out of range exit codes
|
||||
(thanks for tweaking my curiosity about this, Akira Huang).
|
||||
|
||||
35) In "Sed Micro-Primer" appendix:
|
||||
Added use of backslash as newline.
|
||||
Added example of operation(s) over an address range.
|
||||
|
||||
36) In "Bibliography" section:
|
||||
Added Pickover entry.
|
||||
|
||||
37) Clarifications in "Copyright" appendix.
|
||||
|
||||
38) Various minor edits to various example scripts.
|
||||
|
||||
|
||||
|
||||
Version 1.1 release
|
||||
01/06/02
|
||||
|
||||
1) Fix up comments in "weirdvars.sh" example.
|
||||
|
||||
|
@ -629,7 +805,7 @@ In "External Filters, Programs, and Commands" section:
|
|||
Added four sites for example shell scripts.
|
||||
Added reference to Rick Hohensee's shell-scripted virtual machine + assembler.
|
||||
|
||||
17) Added "mail-format.sh" to "Contributed Scripts" section.
|
||||
17) Added "mail-format.sh" to "Contributed Scripts" appendix.
|
||||
|
||||
18) In "Tests" section:
|
||||
Clearer definition of what "test" actually means.
|
||||
|
@ -793,7 +969,7 @@ In "External Filters, Programs, and Commands" section:
|
|||
* Descriptive names for variables added.
|
||||
|
||||
62) Added "copy-cd.sh", a script for copying data CDs, to "Contributed
|
||||
Scripts" section.
|
||||
Scripts" appendix.
|
||||
|
||||
63) In "Loops" section, separated "Loop Control Commands" ("break" and "continue")
|
||||
into a separate subsection.
|
||||
|
@ -1192,7 +1368,7 @@ In "External Filters, Programs, and Commands" section:
|
|||
Added using "[[ ]]" and "(( ))" in comparisons.
|
||||
Corrections in discussion of interactive shells, plus
|
||||
illustrative example.
|
||||
In "Contributed Scripts" section:
|
||||
In "Contributed Scripts" appendix:
|
||||
Added "primes.sh" to demonstrate that arrays are not need to
|
||||
generate prime numbers.
|
||||
Added comments to "manview.sh"
|
||||
|
@ -1246,7 +1422,7 @@ Comments: Another major improvement. The HOWTO is nearly book length,
|
|||
Changes from version 0.2:
|
||||
|
||||
1) Fixed:
|
||||
Renamed Example A-2 in Appendix A (Contributed Scripts) to
|
||||
Renamed Example A-2 in Appendix A (Contributed Scripts appendix) to
|
||||
"encryptedpw". It had previously been named "manview", duplicating
|
||||
the title of Example A-1.
|
||||
|
||||
|
@ -1299,20 +1475,20 @@ In "External Filters, Programs, and Commands" section:
|
|||
21) Added "su" to "System and Administrative Commands" section.
|
||||
|
||||
22) Added Jim Van Zandt's "daily backup" example script
|
||||
to "Contrib-Scripts" section.
|
||||
to "Contrib-Scripts" appendix.
|
||||
|
||||
23) Enhanced example 66 (ex66.sh) on arrays with more methods of initializing
|
||||
array variables.
|
||||
|
||||
24) Corrected "Siever" entry in bibliography.
|
||||
|
||||
25) Added Jordi Sanfeliu's "tree" script to "Contrib-Scripts" section.
|
||||
25) Added Jordi Sanfeliu's "tree" script to "Contrib-Scripts" appendix.
|
||||
|
||||
26) Added Robbins' "Bash Reference Card" to bibliography.
|
||||
|
||||
27) Added reference to Duarte's sed tutorial in bibliography.
|
||||
|
||||
28) Added "rn.sh", file rename utility to "Contrib-Scripts" section.
|
||||
28) Added "rn.sh", file rename utility to "Contrib-Scripts" appendix.
|
||||
|
||||
29) Added "initializing multiple variables on same line" to ex9.sh.
|
||||
|
||||
|
@ -1625,7 +1801,7 @@ Other changes
|
|||
subsection 'Optimizations'
|
||||
subsection 'Assorted Tips'
|
||||
|
||||
56) Contrib script section added
|
||||
56) Contrib script section added.
|
||||
4 scripts so far.
|
||||
|
||||
57) Expanded 'Credits' section.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,12 +20,10 @@ exit 0
|
|||
|
||||
ROOTUSER_NAME=root
|
||||
|
||||
username=`id -nu`
|
||||
username=`id -nu` # Or... username=`whoami`
|
||||
if [ "$username" = "$ROOTUSER_NAME" ]
|
||||
then
|
||||
echo "Rooty, toot, toot. You are root."
|
||||
else
|
||||
echo "You are just a regular fella."
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -16,7 +16,7 @@ echo -n "$n "
|
|||
|
||||
: $[ n = $n + 1 ]
|
||||
# ":" necessary because otherwise Bash attempts
|
||||
#+ to interpret "$((n = $n + 1))" as a command.
|
||||
#+ to interpret "$[ n = $n + 1 ]" as a command.
|
||||
# Works even if "n" was initialized as a string.
|
||||
echo -n "$n "
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ assert () # If condition false,
|
|||
if [ ! $1 ]
|
||||
then
|
||||
echo "Assertion failed: \"$1\""
|
||||
echo "File $0, line $lineno"
|
||||
echo "File \"$0\", line $lineno"
|
||||
exit $E_ASSERT_FAILED
|
||||
# else
|
||||
# return
|
||||
|
@ -38,6 +38,8 @@ assert "$condition" $LINENO
|
|||
|
||||
# Some commands.
|
||||
# ...
|
||||
echo "You will never see this statement echo."
|
||||
# ...
|
||||
# Some more commands.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -18,7 +18,7 @@ else
|
|||
done
|
||||
fi
|
||||
|
||||
# ==> Exercise for the reader: Add error checking and other options.
|
||||
# ==> Exercise: Add error checking and other options.
|
||||
# ==>
|
||||
# ==> Note that the small sed script repeats, except for the arg passed.
|
||||
# ==> Does it make sense to embed it in a function? Why or why not?
|
||||
|
|
|
@ -3,29 +3,32 @@
|
|||
|
||||
# Recall the algorithm for a bubble sort. In this particular version...
|
||||
|
||||
# With each successive pass through the array to be sorted,
|
||||
# compare two adjacent elements, and swap them if out of order.
|
||||
# At the end of the first pass, the "heaviest" element has sunk to bottom.
|
||||
# At the end of the second pass, the next "heaviest" one has sunk next to bottom.
|
||||
# And so forth.
|
||||
# This means that each successive pass needs to traverse less of the array.
|
||||
# You will therefore notice a speeding up in the printing of the later passes.
|
||||
# With each successive pass through the array to be sorted,
|
||||
#+ compare two adjacent elements, and swap them if out of order.
|
||||
# At the end of the first pass, the "heaviest" element has sunk to bottom.
|
||||
# At the end of the second pass, the next "heaviest" one has sunk next to bottom.
|
||||
# And so forth.
|
||||
# This means that each successive pass needs to traverse less of the array.
|
||||
# You will therefore notice a speeding up in the printing of the later passes.
|
||||
|
||||
|
||||
exchange()
|
||||
{
|
||||
# Swaps two members of the array.
|
||||
local temp=${Countries[$1]} # Temporary storage for element getting swapped out.
|
||||
local temp=${Countries[$1]} # Temporary storage
|
||||
#+ for element getting swapped out.
|
||||
Countries[$1]=${Countries[$2]}
|
||||
Countries[$2]=$temp
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
declare -a Countries # Declare array, optional here since it's initialized below.
|
||||
declare -a Countries # Declare array,
|
||||
#+ optional here since it's initialized below.
|
||||
|
||||
Countries=(Netherlands Ukraine Zaire Turkey Russia Yemen Syria Brazil Argentina Nicaragua Japan Mexico Venezuela Greece England Israel Peru Canada Oman Denmark Wales France Kenya Qatar Liechtenstein Hungary)
|
||||
# Couldn't think of one starting with X (darn!).
|
||||
Countries=(Netherlands Ukraine Zaire Turkey Russia Yemen Syria Brazil Argentina Nicaragua Japan Mexico Venezuela Greece England Israel Peru Canada Oman Denmark Wales France Kenya Xanadu Qatar Liechtenstein Hungary)
|
||||
# "Xanadu" is the mythical place where, according to Coleridge,
|
||||
#+ Kubla Khan did a pleasure dome decree.
|
||||
|
||||
clear # Clear the screen to start with.
|
||||
|
||||
|
@ -44,11 +47,12 @@ do
|
|||
while [ "$index" -lt "$comparisons" ] # Beginning of inner loop
|
||||
do
|
||||
if [ ${Countries[$index]} \> ${Countries[`expr $index + 1`]} ]
|
||||
# If out of order...
|
||||
# Recalling that \> is ASCII comparison operator.
|
||||
# If out of order...
|
||||
# Recalling that \> is ASCII comparison operator
|
||||
#+ within single brackets.
|
||||
|
||||
# if [[ ${Countries[$index]} > ${Countries[`expr $index + 1`]} ]]
|
||||
# also works.
|
||||
# if [[ ${Countries[$index]} > ${Countries[`expr $index + 1`]} ]]
|
||||
#+ also works.
|
||||
then
|
||||
exchange $index `expr $index + 1` # Swap.
|
||||
fi
|
||||
|
@ -56,8 +60,8 @@ do
|
|||
done # End of inner loop
|
||||
|
||||
|
||||
let "comparisons -= 1" # Since "heaviest" element bubbles to bottom,
|
||||
# we need do one less comparison each pass.
|
||||
let "comparisons -= 1" # Since "heaviest" element bubbles to bottom,
|
||||
#+ we need do one less comparison each pass.
|
||||
|
||||
echo
|
||||
echo "$count: ${Countries[@]}" # Print resultant array at end of each pass.
|
||||
|
@ -65,7 +69,6 @@ echo
|
|||
let "count += 1" # Increment pass count.
|
||||
|
||||
done # End of outer loop
|
||||
|
||||
# All done.
|
||||
# All done.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -48,6 +48,7 @@ exit 0
|
|||
|
||||
# As it stands, this script must be terminated with a Control-C.
|
||||
|
||||
# Exercises for the reader:
|
||||
# Exercises:
|
||||
# ---------
|
||||
# Improve the script so it exits on a "q" keystroke.
|
||||
# Make the script more user-friendly in other ways.
|
||||
|
|
|
@ -22,7 +22,7 @@ done
|
|||
|
||||
echo; echo
|
||||
|
||||
# Exercise for the reader:
|
||||
# Exercise:
|
||||
# Come up with a meaningful use for "continue N" in a script.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -43,7 +43,7 @@ esac
|
|||
|
||||
echo
|
||||
|
||||
# Exercise for the reader:
|
||||
# Exercise:
|
||||
# Change the above "case" statement to also accept "yes" and "Yes" as input.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -45,7 +45,8 @@ check_date () # Checks for invalid date(s) passed.
|
|||
[ "$day" -gt "$DIM" ] || [ "$month" -gt "$MIY" ] || [ "$year" -lt "$REFYR" ] && Param_Error
|
||||
# Exit script on bad value(s).
|
||||
# Uses "or-list / and-list".
|
||||
# Exercise for the reader: Implement more rigorous date checking.
|
||||
#
|
||||
# Exercise: Implement more rigorous date checking.
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,16 +4,18 @@
|
|||
echo; echo
|
||||
|
||||
echo "\v\v\v\v" # Prints \v\v\v\v
|
||||
# Must use the -e option with 'echo' to print escaped characters.
|
||||
# Use the -e option with 'echo' to print escaped characters.
|
||||
echo -e "\v\v\v\v" # Prints 4 vertical tabs.
|
||||
echo -e "\042" # Prints " (quote, octal ASCII character 42).
|
||||
|
||||
# The $'\X' construct makes the -e option unnecessary.
|
||||
echo $'\n' # Newline.
|
||||
echo $'\a' # Alert (beep).
|
||||
|
||||
# Bash, version 2 and later, permits using the $'\xxx' construct.
|
||||
echo $'\n'
|
||||
echo $'\a'
|
||||
# Version 2 and later of Bash permits using the $'\xxx' construct.
|
||||
echo $'\t \042 \t' # Quote (") framed by tabs.
|
||||
|
||||
|
||||
# Assigning ASCII characters to a variable.
|
||||
# ----------------------------------------
|
||||
quote=$'\042' # " assigned to a variable.
|
||||
|
@ -22,7 +24,7 @@ echo "$quote This is a quoted string, $quote and this lies outside the quotes."
|
|||
echo
|
||||
|
||||
# Concatenating ASCII chars in a variable.
|
||||
triple_underline=$'\137\137\137' # 137 is octal ASCII code for "_".
|
||||
triple_underline=$'\137\137\137' # 137 is octal ASCII code for '_'.
|
||||
echo "$triple_underline UNDERLINE $triple_underline"
|
||||
|
||||
ABC=$'\101\102\103\010' # 101, 102, 103 are octal A, B, C.
|
||||
|
@ -32,6 +34,7 @@ echo; echo
|
|||
|
||||
escape=$'\033' # 033 is octal for escape.
|
||||
echo "\"escape\" echoes as $escape"
|
||||
# no visible output.
|
||||
|
||||
echo; echo
|
||||
|
||||
|
|
|
@ -8,7 +8,27 @@ then
|
|||
echo "0 is true."
|
||||
else
|
||||
echo "0 is false."
|
||||
fi
|
||||
fi # 0 is true.
|
||||
|
||||
echo
|
||||
|
||||
echo "Testing \"1\""
|
||||
if [ 1 ] # one
|
||||
then
|
||||
echo "1 is true."
|
||||
else
|
||||
echo "1 is false."
|
||||
fi # 1 is true.
|
||||
|
||||
echo
|
||||
|
||||
echo "Testing \"-1\""
|
||||
if [ -1 ] # minus one
|
||||
then
|
||||
echo "-1 is true."
|
||||
else
|
||||
echo "-1 is false."
|
||||
fi # -1 is true.
|
||||
|
||||
echo
|
||||
|
||||
|
@ -18,7 +38,7 @@ then
|
|||
echo "NULL is true."
|
||||
else
|
||||
echo "NULL is false."
|
||||
fi
|
||||
fi # NULL is false.
|
||||
|
||||
echo
|
||||
|
||||
|
@ -28,7 +48,7 @@ then
|
|||
echo "Random string is true."
|
||||
else
|
||||
echo "Random string is false."
|
||||
fi
|
||||
fi # Random string is true.
|
||||
|
||||
echo
|
||||
|
||||
|
@ -39,7 +59,7 @@ then
|
|||
echo "Uninitialized variable is true."
|
||||
else
|
||||
echo "Uninitialized variable is false."
|
||||
fi
|
||||
fi # Uninitialized variable is false.
|
||||
|
||||
echo
|
||||
|
||||
|
@ -49,11 +69,12 @@ then
|
|||
echo "Uninitialized variable is true."
|
||||
else
|
||||
echo "Uninitialized variable is false."
|
||||
fi
|
||||
fi # Uninitialized variable is false.
|
||||
|
||||
echo
|
||||
|
||||
xyz= # Initialized, but set to null value.
|
||||
|
||||
xyz= # Initialized, but set to null value.
|
||||
|
||||
echo "Testing \"-n \$xyz\""
|
||||
if [ -n "$xyz" ]
|
||||
|
@ -61,7 +82,7 @@ then
|
|||
echo "Null variable is true."
|
||||
else
|
||||
echo "Null variable is false."
|
||||
fi
|
||||
fi # Null variable is false.
|
||||
|
||||
|
||||
echo
|
||||
|
@ -75,7 +96,7 @@ then
|
|||
echo "\"false\" is true." #+ and it tests true.
|
||||
else
|
||||
echo "\"false\" is false."
|
||||
fi
|
||||
fi # "false" is true.
|
||||
|
||||
echo
|
||||
|
||||
|
@ -85,7 +106,8 @@ then
|
|||
echo "\"\$false\" is true."
|
||||
else
|
||||
echo "\"\$false\" is false."
|
||||
fi # Now, we get the expected result.
|
||||
fi # "$false" is false.
|
||||
# Now, we get the expected result.
|
||||
|
||||
|
||||
echo
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
filename=sys.log
|
||||
|
||||
cat /dev/null > $filename; echo "Creating / cleaning out file."
|
||||
# Creates file if it does not already exist,
|
||||
# and truncates it to zero length if it does.
|
||||
# : > filename also works.
|
||||
# Creates file if it does not already exist,
|
||||
#+ and truncates it to zero length if it does.
|
||||
# : > filename also works.
|
||||
|
||||
tail /var/log/messages > $filename
|
||||
# /var/log/messages must have world read permission for this to work.
|
||||
|
|
|
@ -5,12 +5,18 @@ echo $a
|
|||
b=$a
|
||||
echo $b
|
||||
|
||||
# Now, getting a little bit fancier...
|
||||
# Now, getting a little bit fancier (command substitution).
|
||||
|
||||
a=`echo Hello!` # Assigns result of 'echo' command to 'a'
|
||||
echo $a
|
||||
# Note that using an exclamation mark (!) in command substitution
|
||||
#+ will not work from the command line,
|
||||
#+ since this triggers the Bash "history mechanism".
|
||||
|
||||
a=`ls -l` # Assigns result of 'ls -l' command to 'a'
|
||||
echo $a
|
||||
echo $a # Unquoted, however, removes tabs and newlines.
|
||||
echo
|
||||
echo "$a" # The quoted variable preserves whitespace.
|
||||
# (See the chapter on "Quoting.")
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#!/bin/bash
|
||||
# Using 'shift' to step through all the positional parameters.
|
||||
|
||||
# Name this script something like shft,
|
||||
# and invoke it with some parameters, for example
|
||||
# ./shft a b c def 23 skidoo
|
||||
# Name this script something like shft,
|
||||
#+ and invoke it with some parameters, for example
|
||||
# ./shft a b c def 23 skidoo
|
||||
|
||||
until [ -z "$1" ] # Until all parameters used up...
|
||||
do
|
||||
|
@ -11,6 +11,6 @@ do
|
|||
shift
|
||||
done
|
||||
|
||||
echo # Extra line feed.
|
||||
echo # Extra line feed.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -36,12 +36,12 @@ fi
|
|||
# * ) lines=$1;;
|
||||
# esac
|
||||
#
|
||||
#* Skip ahead to "Loops" to understand this.
|
||||
#* Skip ahead to "Loops" chapter to understand this.
|
||||
|
||||
|
||||
cd $LOG_DIR
|
||||
|
||||
if [ `pwd` != "$LOG_DIR" ] # or if [ "$PWD" != "LOG_DIR" ]
|
||||
if [ `pwd` != "$LOG_DIR" ] # or if [ "$PWD" != "$LOG_DIR" ]
|
||||
# Not in /var/log?
|
||||
then
|
||||
echo "Can't change to $LOG_DIR."
|
||||
|
|
|
@ -7,8 +7,8 @@ do
|
|||
echo -n "$a "
|
||||
done
|
||||
|
||||
# The 'in list' missing, therefore the loop operates on '$@'
|
||||
# (command-line argument list, including whitespace).
|
||||
# The 'in list' missing, therefore the loop operates on '$@'
|
||||
#+ (command-line argument list, including whitespace).
|
||||
|
||||
echo
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ previous=$var1
|
|||
while echo "previous-variable = $previous"
|
||||
echo
|
||||
previous=$var1
|
||||
[ "$var1" != end ] # Keeps track of what "var1" was previously.
|
||||
[ "$var1" != end ] # Keeps track of what $var1 was previously.
|
||||
# Four conditions on "while", but only last one controls loop.
|
||||
# The *last* exit status is the one that counts.
|
||||
do
|
||||
|
|
|
@ -19,7 +19,7 @@ do
|
|||
echo -n "$a "
|
||||
done
|
||||
|
||||
# Exercise for the reader:
|
||||
# Exercise:
|
||||
# Why does loop print up to 20?
|
||||
|
||||
echo; echo
|
||||
|
|
|
@ -10,7 +10,8 @@ case "$Keypress" in
|
|||
* ) echo "Punctuation, whitespace, or other";;
|
||||
esac # Allows ranges of characters in [square brackets].
|
||||
|
||||
# Exercise for the reader:
|
||||
# Exercise:
|
||||
# --------
|
||||
# As the script stands, # it accepts a single keystroke, then terminates.
|
||||
# Change the script so it accepts continuous input,
|
||||
# reports on each keystroke, and terminates only when "X" is hit.
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
# invoked from the command line.
|
||||
|
||||
sed -e /^$/d "$1"
|
||||
# The '-e' means an "editing" command follows (optional here).
|
||||
# '^' is the beginning of line, '$' is the end.
|
||||
# This match lines with nothing between the beginning and the end,
|
||||
# blank lines.
|
||||
# The 'd' is the delete command.
|
||||
# The '-e' means an "editing" command follows (optional here).
|
||||
# '^' is the beginning of line, '$' is the end.
|
||||
# This match lines with nothing between the beginning and the end,
|
||||
#+ blank lines.
|
||||
# The 'd' is the delete command.
|
||||
|
||||
# Quoting the command-line arg permits
|
||||
# whitespace and special characters in the filename.
|
||||
# Quoting the command-line arg permits
|
||||
#+ whitespace and special characters in the filename.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -58,8 +58,9 @@ esac
|
|||
|
||||
echo
|
||||
|
||||
# Exercise for the reader:
|
||||
# Change the script so it accepts continuous input,
|
||||
# instead of terminating after displaying just one address.
|
||||
# Exercise:
|
||||
# --------
|
||||
# Change the script so it accepts continuous input,
|
||||
#+ instead of terminating after displaying just one address.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
. data-file # Load a data file.
|
||||
# Same effect as "source data-file", but more portable.
|
||||
|
||||
# The file "data-file" must be present in current working directory,
|
||||
# since it is referred to by its 'basename'.
|
||||
# The file "data-file" must be present in current working directory,
|
||||
#+ since it is referred to by its 'basename'.
|
||||
|
||||
# Now, reference some data from that file.
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#!/bin/bash
|
||||
|
||||
SPEED=2 # May use higher speed if supported.
|
||||
SPEED=2 # May use higher speed if your hardware supports it.
|
||||
IMAGEFILE=cdimage.iso
|
||||
CONTENTSFILE=contents
|
||||
DEFAULTDIR=/opt
|
||||
DEFAULTDIR=/opt # Make sure this directory exists.
|
||||
|
||||
# Script to automate burning a CDR.
|
||||
|
||||
# Uses Joerg Schilling's "cdrecord" package.
|
||||
# (http://www.fokus.gmd.de/nthp/employees/schilling/cdrecord.html)
|
||||
|
||||
# If this script invoked as an ordinary user, need to suid cdrecord
|
||||
# (chmod u+s /usr/bin/cdrecord, as root).
|
||||
# If this script invoked as an ordinary user, need to suid cdrecord
|
||||
#+ (chmod u+s /usr/bin/cdrecord, as root).
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
y=`eval ls -l` # Similar to y=`ls -l`
|
||||
echo $y # but linefeeds removed.
|
||||
y=`eval ls -l` # Similar to y=`ls -l`
|
||||
echo $y # but linefeeds removed because "echoed" variable is unquoted.
|
||||
echo
|
||||
echo "$y" # Linefeeds preserved when variable is quoted.
|
||||
|
||||
y=`eval df` # Similar to y=`df`
|
||||
echo $y # but linefeeds removed.
|
||||
echo; echo
|
||||
|
||||
# Since LF's not preserved, it may make it easier to parse output.
|
||||
y=`eval df` # Similar to y=`df`
|
||||
echo $y # but linefeeds removed.
|
||||
|
||||
# When LF's not preserved, it may make it easier to parse output,
|
||||
#+ using utilities such as "awk".
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo hello
|
||||
echo $? # Exit status 0 returned because command successful.
|
||||
echo $? # Exit status 0 returned because command executed successfully.
|
||||
|
||||
lskdf # Unrecognized command.
|
||||
echo $? # Non-zero exit status returned.
|
||||
echo $? # Non-zero exit status returned because command failed to execute.
|
||||
|
||||
echo
|
||||
|
||||
exit 113 # Will return 113 to shell.
|
||||
# To verify this, type "echo $?" after script terminates.
|
||||
# To verify this, type "echo $?" after script terminates.
|
||||
|
||||
# By convention, an 'exit 0' indicates success,
|
||||
# while a non-zero exit value means an error or anomalous condition.
|
||||
# By convention, an 'exit 0' indicates success,
|
||||
#+ while a non-zero exit value means an error or anomalous condition.
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
# Range: 0 - 200
|
||||
# It's crude, but it works.
|
||||
|
||||
# Extending the range and otherwise improving the script
|
||||
# is left as an exercise for the reader.
|
||||
# Extending the range and otherwise improving the script is left as an exercise.
|
||||
|
||||
# Usage: roman number-to-convert
|
||||
|
||||
|
@ -40,7 +39,8 @@ do
|
|||
done
|
||||
|
||||
return $number
|
||||
# Exercise for the reader:
|
||||
# Exercise:
|
||||
# --------
|
||||
# Explain how this function works.
|
||||
# Hint: division by successive subtraction.
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Non-interactive use of 'vi' to edit a file.
|
||||
# (Will not work with 'vim', for some reason.)
|
||||
# Emulates 'sed'.
|
||||
|
||||
E_BADARGS=65
|
||||
|
@ -25,7 +24,10 @@ ZZ
|
|||
x23LimitStringx23
|
||||
#----------End here document-----------#
|
||||
|
||||
# Note that ^[ above is a literal escape
|
||||
# typed by Control-V Escape.
|
||||
# Note that ^[ above is a literal escape
|
||||
#+ typed by Control-V <Esc>.
|
||||
|
||||
# Bram Moolenaar points out that this may not work with 'vim',
|
||||
#+ because of possible problems with terminal interaction.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -20,7 +20,7 @@ hello=$a
|
|||
echo hello # Not a variable reference, just the string "hello".
|
||||
|
||||
echo $hello
|
||||
echo ${hello} #Identical to above.
|
||||
echo ${hello} # Identical to above.
|
||||
|
||||
echo "$hello"
|
||||
echo "${hello}"
|
||||
|
@ -28,14 +28,14 @@ echo "${hello}"
|
|||
echo
|
||||
|
||||
hello="A B C D"
|
||||
echo $hello
|
||||
echo "$hello"
|
||||
# Now, echo $hello and echo "$hello" give different results.
|
||||
echo $hello # A B C D
|
||||
echo "$hello" # A B C D
|
||||
# As you see, echo $hello and echo "$hello" give different results.
|
||||
# Quoting a variable preserves whitespace.
|
||||
|
||||
echo
|
||||
|
||||
echo '$hello'
|
||||
echo '$hello' # $hello
|
||||
# Variable referencing disabled by single quotes,
|
||||
#+ which causes the "$" to be interpreted literally.
|
||||
|
||||
|
@ -67,7 +67,7 @@ numbers="one two three"
|
|||
other_numbers="1 2 3"
|
||||
# If whitespace within a variable, then quotes necessary.
|
||||
echo "numbers = $numbers"
|
||||
echo "other_numbers = $other_numbers"
|
||||
echo "other_numbers = $other_numbers" # other_numbers = 1 2 3
|
||||
echo
|
||||
|
||||
echo "uninitialized_variable = $uninitialized_variable"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
# findstring.sh: Find a particular string in binaries in a specified directory.
|
||||
# findstring.sh:
|
||||
# Find a particular string in binaries in a specified directory.
|
||||
|
||||
directory=/usr/bin/
|
||||
fstring="Free Software Foundation" # See which files come from the FSF.
|
||||
|
@ -7,12 +8,15 @@ fstring="Free Software Foundation" # See which files come from the FSF.
|
|||
for file in $( find $directory -type f -name '*' | sort )
|
||||
do
|
||||
strings -f $file | grep "$fstring" | sed -e "s%$directory%%"
|
||||
# In the "sed" expression, it is necessary to substitute for the normal "/" delimiter
|
||||
# because "/" happens to be one of the characters filtered out.
|
||||
# Failure to do so gives an error message (try it).
|
||||
# In the "sed" expression,
|
||||
#+ it is necessary to substitute for the normal "/" delimiter
|
||||
#+ because "/" happens to be one of the characters filtered out.
|
||||
# Failure to do so gives an error message (try it).
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
||||
# Exercise for the reader (easy):
|
||||
# Convert this script to taking command-line parameters for $directory and $fstring.
|
||||
# Exercise (easy):
|
||||
# ---------------
|
||||
# Convert this script to taking command-line parameters
|
||||
#+ for $directory and $fstring.
|
||||
|
|
|
@ -96,6 +96,7 @@ rm -f ${TMPFILE}
|
|||
# ==> Finally, tempfile deleted (you may wish to copy it to a logfile).
|
||||
|
||||
|
||||
# ==> Exercises for reader:
|
||||
# ==> Exercises:
|
||||
# ==> ---------
|
||||
# ==> 1) Add error checking.
|
||||
# ==> 2) Add bells & whistles.
|
||||
|
|
|
@ -28,7 +28,7 @@ echo
|
|||
|
||||
exit 0
|
||||
|
||||
# Exercises for reader:
|
||||
# --------------------
|
||||
# Exercises:
|
||||
# ---------
|
||||
# 1) Add newlines to output, if more than one match in any given file.
|
||||
# 2) Add features.
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
# Strings
|
||||
string=abcdA01
|
||||
echo "len($string)" | m4 # 7
|
||||
echo "substr($string,4)" | m4 # A01
|
||||
echo "len($string)" | m4 # 7
|
||||
echo "substr($string,4)" | m4 # A01
|
||||
echo "regexp($string,[0-1][0-1],\&Z)" | m4 # 01Z
|
||||
|
||||
# Arithmetic
|
||||
echo "incr(22)" | m4 # 23
|
||||
echo "eval(99 / 3)" | m4 # 33
|
||||
echo "incr(22)" | m4 # 23
|
||||
echo "eval(99 / 3)" | m4 # 33
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
# Gets rid of carets, tabs, also fold excessively long lines.
|
||||
|
||||
# =================================================================
|
||||
# Standard Check for Script Argument(s)
|
||||
ARGS=1
|
||||
E_BADARGS=65
|
||||
E_NOFILE=66
|
||||
|
@ -20,9 +22,12 @@ else
|
|||
echo "File \"$1\" does not exist."
|
||||
exit $E_NOFILE
|
||||
fi
|
||||
# =================================================================
|
||||
|
||||
MAXWIDTH=70 # Width to fold long lines to.
|
||||
|
||||
# Delete carets and tabs at beginning of lines,
|
||||
#+ then fold lines to $MAXWIDTH characters.
|
||||
sed '
|
||||
s/^>//
|
||||
s/^ *>//
|
||||
|
@ -31,7 +36,10 @@ s/ *//
|
|||
' $1 | fold -s --width=$MAXWIDTH
|
||||
# -s option to "fold" breaks lines at whitespace, if possible.
|
||||
|
||||
# This script was inspired by an article in a well-known trade journal
|
||||
# extolling a 164K Windows utility with similar functionality.
|
||||
# This script was inspired by an article in a well-known trade journal
|
||||
#+ extolling a 164K Windows utility with similar functionality.
|
||||
#
|
||||
# An nice set of text processing utilities and an efficient
|
||||
#+ scripting language makes unnecessary bloated executables.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -40,6 +40,7 @@ fi
|
|||
|
||||
exit 0
|
||||
|
||||
# Exercise for the reader (easy):
|
||||
# Convert this to an interactive script,
|
||||
# that is, have the script ask for input (two numbers).
|
||||
# Exercise (easy):
|
||||
# ---------------
|
||||
# Convert this to an interactive script,
|
||||
#+ that is, have the script ask for input (two numbers).
|
||||
|
|
|
@ -2,35 +2,49 @@
|
|||
# numbers.sh: Representation of numbers.
|
||||
|
||||
# Decimal
|
||||
let "d = 32"
|
||||
echo "d = $d"
|
||||
let "dec = 32"
|
||||
echo "decimal number = $dec" # 32
|
||||
# Nothing out of the ordinary here.
|
||||
|
||||
|
||||
# Octal: numbers preceded by '0' (zero)
|
||||
let "o = 071"
|
||||
echo "o = $o"
|
||||
let "oct = 071"
|
||||
echo "octal number = $oct" # 57
|
||||
# Expresses result in decimal.
|
||||
|
||||
# Hexadecimal: numbers preceded by '0x' or '0X'
|
||||
let "h = 0x7a"
|
||||
echo "h = $h"
|
||||
let "hex = 0x7a"
|
||||
echo "hexadecimal number = $hex" # 122
|
||||
# Expresses result in decimal.
|
||||
|
||||
# Other bases: BASE#NUMBER
|
||||
# BASE between 2 and 36.
|
||||
let "b = 32#77"
|
||||
echo "b = $b"
|
||||
# BASE between 2 and 64.
|
||||
|
||||
let "bin = 2#111100111001101"
|
||||
echo "binary number = $bin" # 31181
|
||||
|
||||
let "b32 = 32#77"
|
||||
echo "base-32 number = $b32" # 231
|
||||
|
||||
let "b64 = 64#@_"
|
||||
echo "base-64 number = $b64" # 4094
|
||||
#
|
||||
# This notation only works for a limited range (2 - 36)
|
||||
# ... 10 digits + 26 alpha characters = 36.
|
||||
let "c = 2#47" # Out of range error:
|
||||
# numbers.sh: let: c = 2#47: value too great for base (error token is "2#47")
|
||||
echo "c = $c"
|
||||
# This notation only works for a limited range (2 - 64)
|
||||
# 10 digits + 26 lowercase characters + 26 uppercase characters + @ + _
|
||||
|
||||
echo
|
||||
|
||||
echo $((36#zz)) $((2#10101010)) $((16#AF16))
|
||||
echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))
|
||||
# 1295 170 44822 3375
|
||||
|
||||
|
||||
# Important note:
|
||||
# Using a digit out of range of the specified base notation
|
||||
#+ will give an error message.
|
||||
|
||||
let "bad_oct = 081"
|
||||
# numbers.sh: let: oct = 081: value too great for base (error token is "081")
|
||||
# Octal numbers use only digits in the range of 0 - 7.
|
||||
|
||||
exit 0
|
||||
# Thanks, S.C., for clarification.
|
||||
# Thanks, Rich Bartell and Stephane Chazelas, for clarification.
|
||||
|
|
|
@ -73,5 +73,5 @@ do echo -n .
|
|||
done
|
||||
echo "On-line"
|
||||
|
||||
# Exercise: Consider the strengths and weaknesses
|
||||
# of each of these approaches.
|
||||
# Exercise: Discuss the strengths and weaknesses
|
||||
# of each of these various approaches.
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#!/bin/bash
|
||||
# primes.sh: Generate prime numbers, without using arrays.
|
||||
# Script contributed by Stephane Chazelas.
|
||||
|
||||
# This does *not* use the classic "Sieve of Erastosthenes" algorithm,
|
||||
#+ but instead uses the more intuitive method of testing each candidate number
|
||||
#+ for factors (divisors), using the "%" modulo operator.
|
||||
#
|
||||
# Script contributed by Stephane Chazelas,
|
||||
|
||||
|
||||
LIMIT=1000 # Primes 2 - 1000
|
||||
|
@ -31,7 +30,7 @@ Primes()
|
|||
|
||||
Primes $n $@ $n # Recursion outside loop.
|
||||
# Successively accumulate positional parameters.
|
||||
# "$@" is the accumulating list of primes.
|
||||
# "$@" is the accumulating list of primes.
|
||||
}
|
||||
|
||||
Primes 1
|
||||
|
|
|
@ -53,6 +53,5 @@ echo
|
|||
exit 0
|
||||
|
||||
# This is an iterative implementation of the Q-series.
|
||||
# The more intuitive recursive implementation
|
||||
# is left as an exercise for the reader.
|
||||
# The more intuitive recursive implementation is left as an exercise.
|
||||
# Warning: calculating this series recursively takes a *very* long time.
|
||||
|
|
|
@ -57,7 +57,8 @@ print_result
|
|||
# Keep in mind that RANDOM is a pseudorandom generator,
|
||||
# and not a spectacularly good one at that.
|
||||
|
||||
# Exercise for the reader (easy):
|
||||
# Exercise (easy):
|
||||
# ---------------
|
||||
# Rewrite this script to flip a coin 1000 times.
|
||||
# Choices are "HEADS" or "TAILS".
|
||||
|
||||
|
|
|
@ -12,14 +12,14 @@ echo | awk "$AWKSCRIPT"
|
|||
exit 0
|
||||
|
||||
|
||||
# Exercises for the reader:
|
||||
# -------------------------
|
||||
# Exercises:
|
||||
# ---------
|
||||
|
||||
# 1] Using a loop construct, print out 10 different random numbers.
|
||||
# 1) Using a loop construct, print out 10 different random numbers.
|
||||
# (Hint: you must reseed the "srand()" function with a different seed
|
||||
# in each pass through the loop. What happens if you fail to do this?)
|
||||
|
||||
# 2] Using an integer multiplier as a scaling factor, generate random numbers
|
||||
# 2) Using an integer multiplier as a scaling factor, generate random numbers
|
||||
# in the range between 10 and 100.
|
||||
|
||||
# 3] Same as exercise #2, above, but generate random integers this time.
|
||||
# 3) Same as exercise #2, above, but generate random integers this time.
|
||||
|
|
|
@ -19,6 +19,6 @@ fi # Each child script does the same, until
|
|||
#+ a generated $i equals $MAXVAL.
|
||||
|
||||
# Using a "while" loop instead of an "if/then" test causes problems.
|
||||
# Exercise for the reader: Explain why.
|
||||
# Explain why.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -18,8 +18,9 @@ echo $a2
|
|||
echo; echo; echo
|
||||
|
||||
exec 0<&6 6<&-
|
||||
# Now restore stdin from fd #6, where it had been saved,
|
||||
# and close fd #6 ( 6<&- ) to free it for other processes to use.
|
||||
# Now restore stdin from fd #6, where it had been saved,
|
||||
#+ and close fd #6 ( 6<&- ) to free it for other processes to use.
|
||||
#
|
||||
# <&6 6<&- also works.
|
||||
|
||||
echo -n "Enter data "
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
Filename=names.data # Default, if no filename specified.
|
||||
Filename=names.data # Default, if no filename specified.
|
||||
else
|
||||
Filename=$1
|
||||
fi
|
||||
# Filename=${1:-names.data}
|
||||
# can replace the above test (parameter substitution).
|
||||
#+ Filename=${1:-names.data}
|
||||
# can replace the above test (parameter substitution).
|
||||
|
||||
count=0
|
||||
|
||||
|
@ -23,11 +23,12 @@ done <"$Filename" # Redirects stdin to file $Filename.
|
|||
|
||||
echo; echo "$count names read"; echo
|
||||
|
||||
# Note that in some older shell scripting languages,
|
||||
# the redirected loop would run as a subshell.
|
||||
# Note that in some older shell scripting languages,
|
||||
#+ the redirected loop would run as a subshell.
|
||||
# Therefore, $count would return 0, the initialized value outside the loop.
|
||||
# Bash and ksh avoid starting a subshell whenever possible,
|
||||
# so that this script, for example, runs correctly.
|
||||
# Bash and ksh avoid starting a subshell whenever possible,
|
||||
# +so that this script, for example, runs correctly.
|
||||
#
|
||||
# Thanks to Heiner Steven for pointing this out.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
# This is an alternate form of the preceding script.
|
||||
|
||||
# Suggested by Heiner Steven
|
||||
# as a workaround in those situations when a redirect loop
|
||||
# runs as a subshell, and therefore variables inside the loop
|
||||
# do not keep their values upon loop termination.
|
||||
# Suggested by Heiner Steven
|
||||
#+ as a workaround in those situations when a redirect loop
|
||||
#+ runs as a subshell, and therefore variables inside the loop
|
||||
# +do not keep their values upon loop termination.
|
||||
|
||||
|
||||
if [ -z "$1" ]
|
||||
|
|
|
@ -7,10 +7,12 @@ else
|
|||
Filename=$1
|
||||
fi
|
||||
|
||||
line_count=`wc $Filename | awk '{ print $1 }'` # Number of lines in target file.
|
||||
# Very contrived and kludgy, nevertheless shows that
|
||||
# it's possible to redirect stdin within a "for" loop...
|
||||
# if you're clever enough.
|
||||
line_count=`wc $Filename | awk '{ print $1 }'`
|
||||
# Number of lines in target file.
|
||||
#
|
||||
# Very contrived and kludgy, nevertheless shows that
|
||||
#+ it's possible to redirect stdin within a "for" loop...
|
||||
#+ if you're clever enough.
|
||||
#
|
||||
# More concise is line_count=$(wc < "$Filename")
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
ARGS=2
|
||||
E_BADARGS=65
|
||||
|
||||
if [ $# -ne $ARGS ]
|
||||
if [ $# -ne "$ARGS" ]
|
||||
then
|
||||
echo "Usage: `basename $0` old_file_suffix new_file_suffix"
|
||||
exit $E_BADARGS
|
||||
|
@ -24,8 +24,8 @@ for filename in *.$1
|
|||
# Traverse list of files ending with 1st argument.
|
||||
do
|
||||
mv $filename ${filename%$1}$2
|
||||
# Strip off part of filename matching 1st argument,
|
||||
# then append 2nd argument.
|
||||
# Strip off part of filename matching 1st argument,
|
||||
#+ then append 2nd argument.
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#
|
||||
# Very simpleminded filename "rename" utility (based on "lowercase.sh").
|
||||
#
|
||||
# The "ren" utility, by Vladimir Lanin (lanin@csd2.nyu.edu),
|
||||
# does a much better job of this.
|
||||
# The "ren" utility, by Vladimir Lanin (lanin@csd2.nyu.edu),
|
||||
#+ does a much better job of this.
|
||||
|
||||
|
||||
ARGS=2
|
||||
|
@ -41,6 +41,7 @@ fi
|
|||
exit 0
|
||||
|
||||
|
||||
# Exercise for reader:
|
||||
# Exercise:
|
||||
# --------
|
||||
# What type of files will this not work on?
|
||||
# How to fix this?
|
||||
# How can this be fixed?
|
||||
|
|
|
@ -23,22 +23,25 @@ echo; echo
|
|||
|
||||
RANDOM=1 # Same seed for RANDOM...
|
||||
random_numbers # ...reproduces the exact same number series.
|
||||
#
|
||||
# When is it useful to duplicate a "random" number series?
|
||||
|
||||
echo; echo
|
||||
|
||||
RANDOM=2 # Trying again, but with a different seen...
|
||||
RANDOM=2 # Trying again, but with a different seed...
|
||||
random_numbers # gives a different number series.
|
||||
|
||||
echo; echo
|
||||
|
||||
# RANDOM=$$ seeds RANDOM from process id of script.
|
||||
# It is also possible to seed RANDOM from 'time' or 'date'.
|
||||
# It is also possible to seed RANDOM from 'time' or 'date' commands.
|
||||
|
||||
# Getting fancy...
|
||||
SEED=$(head -1 /dev/urandom | od -N 1 | awk '{ print $2 }')
|
||||
# Pseudo-random output fetched from /dev/urandom (system pseudo-random "device"),
|
||||
# then converted to line of printable (octal) numbers by "od",
|
||||
# finally "awk" retrieves just one number for SEED.
|
||||
# Pseudo-random output fetched
|
||||
#+ from /dev/urandom (system pseudo-random device-file),
|
||||
#+ then converted to line of printable (octal) numbers by "od",
|
||||
#+ finally "awk" retrieves just one number for SEED.
|
||||
RANDOM=$SEED
|
||||
random_numbers
|
||||
|
||||
|
|
|
@ -263,7 +263,8 @@ echo
|
|||
|
||||
|
||||
|
||||
# Exercise for reader:
|
||||
# Exercise:
|
||||
# --------
|
||||
# Add code to test all the other string functions above.
|
||||
|
||||
|
||||
|
|
|
@ -37,9 +37,9 @@ sed '
|
|||
# Easy to understand if you take several hours to learn sed fundamentals.
|
||||
|
||||
|
||||
# Need to add one more line to the sed script to deal with
|
||||
# case where line of code has a comment following it on same line.
|
||||
# This is left as a non-trivial exercise for the reader.
|
||||
# Need to add one more line to the sed script to deal with
|
||||
#+ case where line of code has a comment following it on same line.
|
||||
# This is left as a non-trivial exercise.
|
||||
|
||||
# Also, the above code deletes lines with a "*/" or "/*",
|
||||
# not a desirable result.
|
||||
|
|
|
@ -41,12 +41,12 @@ read answer
|
|||
PrintAnswer
|
||||
|
||||
|
||||
# Admittedly, this is a kludgy implementation of timed input,
|
||||
# but pretty much as good as can be done with Bash.
|
||||
# (Challenge to reader: come up with something better.)
|
||||
# Admittedly, this is a kludgy implementation of timed input,
|
||||
#+ however the "-t" option to "read" simplifies this task.
|
||||
# See "t-out.sh", below.
|
||||
|
||||
# If you need something a bit more elegant...
|
||||
# consider writing the application in C or C++,
|
||||
# using appropriate library functions, such as 'alarm' and 'setitimer'.
|
||||
# If you need something really elegant...
|
||||
#+ consider writing the application in C or C++,
|
||||
#+ using appropriate library functions, such as 'alarm' and 'setitimer'.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -71,4 +71,4 @@ done
|
|||
echo "Total directories = $numdirs"
|
||||
|
||||
exit 0
|
||||
# ==> Challenge to reader: try to figure out exactly how this script works.
|
||||
# ==> Challenge: try to figure out exactly how this script works.
|
||||
|
|
|
@ -119,12 +119,12 @@ rotate # Rotate it 45 degrees counterclockwise.
|
|||
|
||||
# This is a rather contrived, not to mention kludgy simulation.
|
||||
#
|
||||
# Exercise #1 for the reader:
|
||||
# Rewrite the array loading and printing functions
|
||||
# in a more intuitive and elegant fashion.
|
||||
# Exercises:
|
||||
# ---------
|
||||
# 1) Rewrite the array loading and printing functions
|
||||
# + in a more intuitive and elegant fashion.
|
||||
#
|
||||
# Exercise #2:
|
||||
# Figure out how the array rotation functions work.
|
||||
# Hint: think about the implications of backwards-indexing an array.
|
||||
# 2) Figure out how the array rotation functions work.
|
||||
# Hint: think about the implications of backwards-indexing an array.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -7,16 +7,14 @@ ARGS=1
|
|||
E_BADARGS=65
|
||||
E_NOFILE=66
|
||||
|
||||
if [ $# -ne $ARGS ] # Correct number of arguments passed to script?
|
||||
if [ $# -ne "$ARGS" ] # Correct number of arguments passed to script?
|
||||
then
|
||||
echo "Usage: `basename $0` filename"
|
||||
exit $E_BADARGS
|
||||
fi
|
||||
|
||||
if [ -f "$1" ] # Check if file exists.
|
||||
if [ ! -f "$1" ] # Check if file exists.
|
||||
then
|
||||
file_name=$1
|
||||
else
|
||||
echo "File \"$1\" does not exist."
|
||||
exit $E_NOFILE
|
||||
fi
|
||||
|
@ -24,7 +22,7 @@ fi
|
|||
|
||||
|
||||
########################################################
|
||||
# main
|
||||
# main ()
|
||||
sed -e 's/\.//g' -e 's/ /\
|
||||
/g' "$1" | tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr
|
||||
# =========================
|
||||
|
@ -36,7 +34,8 @@ sed -e 's/\.//g' -e 's/ /\
|
|||
#+ finally prefix occurrence count and sort numerically.
|
||||
########################################################
|
||||
|
||||
# Exercises for the reader:
|
||||
# Exercises:
|
||||
# ---------
|
||||
# 1) Add 'sed' commands to filter out other punctuation, such as commas.
|
||||
# 2) Modify to also filter out multiple spaces and other whitespace.
|
||||
# 3) Add a secondary sort key, so that instances of equal occurrence
|
||||
|
|
Loading…
Reference in New Issue