mirror of https://github.com/tLDP/LDP
updated
This commit is contained in:
parent
d73bf4f9df
commit
07176b0865
|
@ -6,6 +6,118 @@
|
|||
http://personal.riverusers.com/~thegrendel/Change.log
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Version 3.3
|
||||
Raspberry release, 03/20/05
|
||||
|
||||
1) In the "Starting Off With a Sha-Bang" chapter:
|
||||
Amended footnote [3] to mention a cat / here document.
|
||||
(Thank you, Fabian Kreutz.)
|
||||
Fixed typo in "ex1a.sh" example.
|
||||
(Thank you, Preetam.)
|
||||
Added Larry Wall epigraph.
|
||||
Changed "Important" block to "Tip," and added "generalizing scripts"
|
||||
paragraph.
|
||||
|
||||
2) In "Special Characters" chapter:
|
||||
At "#" entry, noted that if comment follows a command on a line,
|
||||
then whitespace preceding the "#" is necessary.
|
||||
(Thanks, Le Wen.)
|
||||
|
||||
3) In "Basic Commands" section of "External Commands" Chapter:
|
||||
Greatly expanded discussion of "chattr" entry.
|
||||
|
||||
4) In "File and Archiving Commands" section of "External Commands" Chapter:
|
||||
Added "rpm -qf" tip at "rpm" entry.
|
||||
|
||||
5) In "Text Processing" section of "External Commands" Chapter:
|
||||
Added "enscript" entry.
|
||||
At "egrep" and "fgrep" entries.
|
||||
added symbolic link note
|
||||
added "dict-lookup.sh" example script.
|
||||
Updated "wc" entry.
|
||||
|
||||
6) In "Communications Commands" section of "External Commands" chapter:
|
||||
Added "netconfig" entry.
|
||||
|
||||
7) In "Math Commands" section of "External Commands" chapter:
|
||||
Fixup of "hexconvert.sh" example script
|
||||
(had left out initialization of E_NOARGS variable)
|
||||
(Thanks, Stefano Palmeri.)
|
||||
|
||||
8) In "Internal Commands and Builtins" chapter:
|
||||
At "forking/spawning" sidebar:
|
||||
Added "spawn.sh" example
|
||||
|
||||
9) In "Job Control Commands" section of "Internal Commands and Builtins"
|
||||
chapter:
|
||||
Corrected note discussing zombie processes.
|
||||
(Thank you, Alan Sundell.)
|
||||
|
||||
10) In "Here Documents" chapter:
|
||||
Removed reference to 'telnet' -- since it's generally not a good idea.
|
||||
|
||||
11) In "Of Zeroes and Nulls" chapter
|
||||
Added/revised discussion of /dev/zero.
|
||||
|
||||
12) In the "Shell Wrappers" section of "Miscellany" chapter:
|
||||
Added footnote giving examples of system utilities that are really
|
||||
shell wrappers.
|
||||
Added "logging-wrapper.sh" example.
|
||||
|
||||
13) In "Indirect References to Variables" section of "Variables Revisited" chapter:
|
||||
Expanded Nils Radtke's example of building dynamic variable names.
|
||||
|
||||
14) In "Parameter Substitution" section of "Variables Revisited" chapter:
|
||||
Fixed up "ex6.sh" example to make it less ambiguous,
|
||||
per suggestion of "Der Schwadde" . . . ).
|
||||
|
||||
15) In "Miscellaneous Commands" section of "External Commands" Chapter:
|
||||
At "dd" entry," added lowercase conversion in-line example.
|
||||
At "jot/seq" entry, added "letter-count.sh" example script.
|
||||
(Thanks, Stefano Palmeri.)
|
||||
|
||||
16) In "System and Administrative Commands" chapter:
|
||||
At "lockfile" entry, fixed typo in inline example.
|
||||
(Thanks, Andreas Abraham.)
|
||||
At "fuser" entry, added more material.
|
||||
|
||||
17) In "Gotchas" chapter:
|
||||
At "Mixing up '=' and '-eq' entry, fixed typo.
|
||||
(Thanks, Andreas Abraham.)
|
||||
|
||||
18) In "Colorizing Scripts" section of "Miscellany" chapter:
|
||||
Added "horserace.sh" example.
|
||||
(Thanks, Stefano Palmeri.)
|
||||
|
||||
19) In "Redirecting Code Blocks" section of "I/O Redirection" chapter:
|
||||
Added code snippet and commentary to redir2.sh example.
|
||||
(Thank you, Bruno de Oliveira Schneider.)
|
||||
|
||||
20) In "Copyright" chapter:
|
||||
Added second URL for French translation.
|
||||
|
||||
21) In the "Sed and Awk Micro-primer" appendix:
|
||||
Fixed "letter-count.sh" example to work with gawk, ver. 3.1.3.
|
||||
(Thanks to Stefano Palmeri for pointing out the need for a fixup.)
|
||||
Renamed filename to "letter-count2.sh" to accommodate alternate
|
||||
version of script which will appear prior to this one in the text.
|
||||
|
||||
22) In "Contributed Scripts" appendix:
|
||||
Fixups to "wgetter2.bash" script.
|
||||
Added "bashpodder.sh" script.
|
||||
(Thank you, Linc Fessenden.)
|
||||
|
||||
23) In "Writing Scripts" section of "Exercises" appendix:
|
||||
In "Intermediate sub-section":
|
||||
Added "Enforcing Disk Quotas" exercise.
|
||||
|
||||
24) Various miscellaneous fixups and enhancements:
|
||||
In example scripts.
|
||||
In citations of book titles (inserted <citetitle> tag).
|
||||
|
||||
|
||||
|
||||
|
||||
Version 3.2
|
||||
Blueberry release, 02/06/05
|
||||
|
||||
|
|
|
@ -52,4 +52,5 @@ dev-tcp.sh (line 14)
|
|||
archiveweblogs.sh (comment in line 4)
|
||||
multiple-processes.sh (line 61)
|
||||
directory-info.sh (lines 36 and 166)
|
||||
catscripts.sh (lines 12 and 21)
|
||||
is_spammer.bash (comments on various lines)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,13 +23,13 @@ echo -n "$n "
|
|||
: $[ n = $n + 1 ]
|
||||
# ":" necessary because otherwise Bash attempts
|
||||
#+ to interpret "$[ n = $n + 1 ]" as a command.
|
||||
# Works even if "n" was initialized as a string.
|
||||
# Works even if "n" was initialized as a string.
|
||||
echo -n "$n "
|
||||
|
||||
n=$[ $n + 1 ]
|
||||
# Works even if "n" was initialized as a string.
|
||||
#* Avoid this type of construct, since it is obsolete and nonportable.
|
||||
# Thanks, Stephane Chazelas.
|
||||
# Thanks, Stephane Chazelas.
|
||||
echo -n "$n "
|
||||
|
||||
# Now for C-style increment operators.
|
||||
|
|
|
@ -27,6 +27,7 @@ echo "Exit status of \"(( 1 / 2 ))\" is $?." # Rounded off to 0.
|
|||
# 1
|
||||
|
||||
(( 1 / 0 )) 2>/dev/null # Illegal division by 0.
|
||||
# ^^^^^^^^^^^
|
||||
echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1
|
||||
|
||||
# What effect does the "2>/dev/null" have?
|
||||
|
|
|
@ -76,7 +76,8 @@ exit 0
|
|||
|
||||
# The file cannot not be "undeleted" or retrieved by normal methods.
|
||||
# However . . .
|
||||
#+ this simple method would *not* likely withstand forensic analysis.
|
||||
#+ this simple method would *not* likely withstand
|
||||
#+ sophisticated forensic analysis.
|
||||
|
||||
# This script may not play well with a journaled file system.
|
||||
# Exercise: Fix it so it does.
|
||||
|
@ -90,4 +91,4 @@ exit 0
|
|||
# For an in-depth analysis on the topic of file deletion and security,
|
||||
#+ see Peter Gutmann's paper,
|
||||
#+ "Secure Deletion of Data From Magnetic and Solid-State Memory".
|
||||
# http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
|
||||
# http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
#!/bin/bash
|
||||
# cannon.sh: Approximating PI by firing cannonballs.
|
||||
|
||||
# This is a very simple instance of a "Monte Carlo" simulation,
|
||||
# This is a very simple instance of a "Monte Carlo" simulation:
|
||||
#+ a mathematical model of a real-life event,
|
||||
#+ using pseudorandom numbers to emulate random chance.
|
||||
|
||||
# Consider a perfectly square plot of land, 10000 units on a side.
|
||||
# This land has a perfectly circular lake in its center,
|
||||
#+ with a diameter of 10000 units.
|
||||
# The plot is actually all water, except for the four corners.
|
||||
# The plot is actually mostly water, except for land in the four corners.
|
||||
# (Think of it as a square with an inscribed circle.)
|
||||
#
|
||||
# Let us fire iron cannonballs from an old-style cannon
|
||||
#+ at the square of land.
|
||||
# All the shots impact somewhere on the plot of land,
|
||||
# We will fire iron cannonballs from an old-style cannon
|
||||
#+ at the square.
|
||||
# All the shots impact somewhere on the square,
|
||||
#+ either in the lake or on the dry corners.
|
||||
# Since the lake takes up most of the land area,
|
||||
# Since the lake takes up most of the area,
|
||||
#+ most of the shots will SPLASH! into the water.
|
||||
# Just a few shots will THUD! into solid ground
|
||||
#+ in the four corners of the land.
|
||||
#+ in the four corners of the square.
|
||||
#
|
||||
# If we take enough random, unaimed shots at the plot of land,
|
||||
# If we take enough random, unaimed shots at the square,
|
||||
#+ Then the ratio of SPLASHES to total shots will approximate
|
||||
#+ the value of PI/4.
|
||||
#
|
||||
|
@ -32,10 +32,10 @@
|
|||
# Theoretically, the more shots taken, the better the fit.
|
||||
# However, a shell script, as opposed to a compiled language
|
||||
#+ with floating-point math built in, requires a few compromises.
|
||||
# This tends to lower the accuracy of the simulation, unfortunately.
|
||||
# This tends to lower the accuracy of the simulation, of course.
|
||||
|
||||
|
||||
DIMENSION=10000 # Length of each side of the plot of land.
|
||||
DIMENSION=10000 # Length of each side of the plot.
|
||||
# Also sets ceiling for random integers generated.
|
||||
|
||||
MAXSHOTS=1000 # Fire this many shots.
|
||||
|
@ -86,8 +86,8 @@ do
|
|||
printf "Xc = %4d " $xCoord
|
||||
printf "Yc = %4d " $yCoord
|
||||
printf "Distance = %5d " $distance # Distance from
|
||||
#+ center of lake,
|
||||
# the "origin,"
|
||||
#+ center of lake --
|
||||
# the "origin" --
|
||||
#+ coordinate (0,0).
|
||||
|
||||
if [ "$distance" -le "$DIMENSION" ]
|
||||
|
|
|
@ -17,7 +17,7 @@ column_number=$2
|
|||
# Passing shell variables to the awk part of the script is a bit tricky.
|
||||
# See the awk documentation for more details.
|
||||
|
||||
# A multi-line awk script is invoked by awk ' ..... '
|
||||
# A multi-line awk script is invoked by: awk ' ..... '
|
||||
|
||||
|
||||
# Begin awk script.
|
||||
|
@ -36,7 +36,7 @@ END {
|
|||
|
||||
|
||||
# It may not be safe to pass shell variables to an embedded awk script,
|
||||
# so Stephane Chazelas proposes the following alternative:
|
||||
#+ so Stephane Chazelas proposes the following alternative:
|
||||
# ---------------------------------------
|
||||
# awk -v column_number="$column_number" '
|
||||
# { total += $column_number
|
||||
|
|
|
@ -9,7 +9,7 @@ b=5
|
|||
|
||||
# Bash permits integer operations and comparisons on variables
|
||||
#+ whose value consists of all-integer characters.
|
||||
# Caution advised.
|
||||
# Caution advised, however.
|
||||
|
||||
echo
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
#!/bin/bash
|
||||
# zmore
|
||||
|
||||
#View gzipped files with 'most'
|
||||
#View gzipped files with 'more'
|
||||
|
||||
NOARGS=65
|
||||
NOTFOUND=66
|
||||
NOTGZIP=67
|
||||
|
||||
if [ $# -eq 0 ] # same effect as: if [ -z "$1" ]
|
||||
# $1 can exist, but be empty: zmost "" arg2 arg3
|
||||
# $1 can exist, but be empty: zmore "" arg2 arg3
|
||||
then
|
||||
echo "Usage: `basename $0` filename" >&2
|
||||
# Error message to stderr.
|
||||
|
@ -31,11 +32,10 @@ then
|
|||
exit $NOTGZIP
|
||||
fi
|
||||
|
||||
zcat $1 | most
|
||||
zcat $1 | more
|
||||
|
||||
# Uses the file viewer 'most' (similar to 'less').
|
||||
# Later versions of 'most' have file decompression capabilities.
|
||||
# May substitute 'more' or 'less', if desired.
|
||||
# Uses the filter 'more.'
|
||||
# May substitute 'less', if desired.
|
||||
|
||||
|
||||
exit $? # Script returns exit status of pipe.
|
||||
|
|
|
@ -9,10 +9,10 @@ echo $b
|
|||
|
||||
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,
|
||||
# Note that including an exclamation mark (!) within a
|
||||
#+ command substitution construct #+ will not work from the command line,
|
||||
#+ since this triggers the Bash "history mechanism."
|
||||
# Within a script, however, the history functions are disabled.
|
||||
# Inside a script, however, the history functions are disabled.
|
||||
|
||||
a=`ls -l` # Assigns result of 'ls -l' command to 'a'
|
||||
echo $a # Unquoted, however, removes tabs and newlines.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# Run as root, of course.
|
||||
# Insert code here to print error message and exit if not root.
|
||||
|
||||
LOG_DIR=var/log
|
||||
LOG_DIR=/var/log
|
||||
# Variables are better than hard-coded values.
|
||||
cd $LOG_DIR
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# Faxing (must have 'fax' installed).
|
||||
|
||||
EXPECTED_ARGS=2
|
||||
E_BADARGS=65
|
||||
|
|
|
@ -16,12 +16,13 @@ esac # Allows ranges of characters in [square brackets],
|
|||
#+ the tests for lowercase and uppercase characters were
|
||||
#+ [a-z] and [A-Z].
|
||||
# This no longer works in certain locales and/or Linux distros.
|
||||
# POSIX is more portable.
|
||||
# Thanks to Frank Wang for pointing this out.
|
||||
|
||||
# Exercise:
|
||||
# --------
|
||||
# As the script stands, it accepts a single keystroke, then terminates.
|
||||
# Change the script so it accepts continuous input,
|
||||
# Change the script so it accepts repeated input,
|
||||
#+ reports on each keystroke, and terminates only when "X" is hit.
|
||||
# Hint: enclose everything in a "while" loop.
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ case "$person" in
|
|||
echo "(212) 533-2814"
|
||||
echo "(212) 533-9972 fax"
|
||||
echo "milliej@loisaida.com"
|
||||
echo "Girlfriend"
|
||||
echo "Ex-girlfriend"
|
||||
echo "Birthday: Feb. 11"
|
||||
;;
|
||||
|
||||
|
@ -59,7 +59,7 @@ echo
|
|||
|
||||
# Exercise:
|
||||
# --------
|
||||
# Change the script so it accepts continuous input,
|
||||
# Change the script so it accepts multiple inputs,
|
||||
#+ instead of terminating after displaying just one address.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# "Reading" variables.
|
||||
|
||||
echo -n "Enter the value of variable 'var1': "
|
||||
# The -n option to echo suppresses newline.
|
||||
|
|
|
@ -11,7 +11,7 @@ $killppp # This variable is now a command.
|
|||
|
||||
# The following operations must be done as root user.
|
||||
|
||||
chmod 666 /dev/ttyS3 # Must be read+write permissions, or else what?
|
||||
chmod 666 /dev/ttyS3 # Restore read+write permissions, or else what?
|
||||
# Since doing a SIGKILL on ppp changed the permissions on the serial port,
|
||||
#+ we restore permissions to previous state.
|
||||
|
||||
|
@ -24,3 +24,5 @@ exit 0
|
|||
# 1) Have script check whether root user is invoking it.
|
||||
# 2) Do a check on whether the process to be killed
|
||||
#+ is actually running before attempting to kill it.
|
||||
# 3) Write an alternate version of this script based on 'fuser':
|
||||
#+ if [ fuser -s /dev/modem ]; then . . .
|
||||
|
|
|
@ -13,9 +13,9 @@ echo
|
|||
printf "Pi to 9 decimal places = %1.9f" $PI # It even rounds off correctly.
|
||||
|
||||
printf "\n" # Prints a line feed,
|
||||
# equivalent to 'echo'.
|
||||
# Equivalent to 'echo' . . .
|
||||
|
||||
printf "Constant = \t%d\n" $DecimalConstant # Inserts tab (\t)
|
||||
printf "Constant = \t%d\n" $DecimalConstant # Inserts tab (\t).
|
||||
|
||||
printf "%s %s \n" $Message1 $Message2
|
||||
|
||||
|
@ -34,6 +34,7 @@ Msg=`printf "%s %s \n" $Message1 $Message2`
|
|||
echo $Msg; echo $Msg
|
||||
|
||||
# As it happens, the 'sprintf' function can now be accessed
|
||||
#+ as a loadable module to Bash, but this is not portable.
|
||||
#+ as a loadable module to Bash,
|
||||
#+ but this is not portable.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#!/bin/bash
|
||||
# badname.sh
|
||||
|
||||
# Delete filenames in current directory containing bad characters.
|
||||
|
||||
for filename in *
|
||||
|
|
|
@ -36,7 +36,7 @@ echo
|
|||
#+ then the script terminates with an error message.
|
||||
|
||||
# You can specify the error message.
|
||||
# : ${ZZXy23AB?"ZZXy23AB has not been set."}
|
||||
# : ${variablename?"ERROR MESSAGE"}
|
||||
|
||||
|
||||
# Same result with: dummy_variable=${ZZXy23AB?}
|
||||
|
@ -53,3 +53,5 @@ echo "You will not see this message, because script already terminated."
|
|||
|
||||
HERE=0
|
||||
exit $HERE # Will NOT exit here.
|
||||
|
||||
# In fact, this script will return an exit status (echo $?) of 1.
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
|
||||
LOWER_LIMIT=1 # Starting with 1.
|
||||
UPPER_LIMIT=1000 # Up to 1000.
|
||||
# (You may set this higher... if you have time on your hands.)
|
||||
# (You may set this higher . . . if you have time on your hands.)
|
||||
|
||||
PRIME=1
|
||||
NON_PRIME=0
|
||||
|
||||
let SPLIT=UPPER_LIMIT/2
|
||||
# Optimization:
|
||||
# Need to test numbers only halfway to upper limit.
|
||||
# Need to test numbers only halfway to upper limit (why?).
|
||||
|
||||
|
||||
declare -a Primes
|
||||
|
@ -104,8 +104,8 @@ exit 0
|
|||
|
||||
|
||||
|
||||
# ----------------------------------------------- #
|
||||
# Code below line will not execute.
|
||||
# -------------------------------------------------------- #
|
||||
# Code below line will not execute, because of 'exit.'
|
||||
|
||||
# This improved version of the Sieve, by Stephane Chazelas,
|
||||
#+ executes somewhat faster.
|
||||
|
|
|
@ -22,6 +22,7 @@ echo "Value of t changed to ${!t}" # 387
|
|||
|
||||
# This is useful for referencing members of an array or table,
|
||||
#+ or for simulating a multi-dimensional array.
|
||||
# An indexing option would have been nice (sigh).
|
||||
# An indexing option (analogous to pointer arithmetic)
|
||||
#+ would have been nice. Sigh.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/bin/bash
|
||||
# May need to be invoked with #!/bin/bash2 on older machines.
|
||||
|
||||
# Cards:
|
||||
# Deals four random hands from a deck of cards.
|
||||
|
@ -17,7 +16,7 @@ CARDS=52
|
|||
declare -a Deck
|
||||
declare -a Suits
|
||||
declare -a Cards
|
||||
# It would have been easier and more intuitive
|
||||
# It would have been easier to implement and more intuitive
|
||||
#+ with a single, 3-dimensional array.
|
||||
# Perhaps a future version of Bash will support multidimensional arrays.
|
||||
|
||||
|
@ -77,6 +76,8 @@ seed_random () # Seed random number generator.
|
|||
seed=`eval date +%s`
|
||||
let "seed %= 32766"
|
||||
RANDOM=$seed
|
||||
# What are some other methods
|
||||
#+ of seeding the random number generator?
|
||||
}
|
||||
|
||||
deal_cards ()
|
||||
|
|
|
@ -7,11 +7,14 @@ hello=$a
|
|||
|
||||
#-------------------------------------------------------------------------
|
||||
# No space permitted on either side of = sign when initializing variables.
|
||||
# What happens if there is a space?
|
||||
|
||||
# If "VARIABLE =value",
|
||||
# ^
|
||||
#+ script tries to run "VARIABLE" command with one argument, "=value".
|
||||
|
||||
# If "VARIABLE= value",
|
||||
# ^
|
||||
#+ script tries to run "value" command with
|
||||
#+ the environmental variable "VARIABLE" set to "".
|
||||
#-------------------------------------------------------------------------
|
||||
|
@ -31,11 +34,13 @@ hello="A B C D"
|
|||
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' # $hello
|
||||
# ^ ^
|
||||
# Variable referencing disabled by single quotes,
|
||||
#+ which causes the "$" to be interpreted literally.
|
||||
|
||||
|
@ -64,16 +69,18 @@ echo "var1=$var1 var2=$var2 var3=$var3"
|
|||
echo; echo
|
||||
|
||||
numbers="one two three"
|
||||
# ^ ^
|
||||
other_numbers="1 2 3"
|
||||
# If whitespace within a variable, then quotes necessary.
|
||||
# ^ ^
|
||||
# If there is whitespace within a variable, then quotes are necessary.
|
||||
echo "numbers = $numbers"
|
||||
echo "other_numbers = $other_numbers" # other_numbers = 1 2 3
|
||||
echo
|
||||
|
||||
echo "uninitialized_variable = $uninitialized_variable"
|
||||
# Uninitialized variable has null value (no value at all).
|
||||
uninitialized_variable= # Declaring, but not initializing it
|
||||
#+ (same as setting it to a null value, as above).
|
||||
uninitialized_variable= # Declaring, but not initializing it --
|
||||
#+ same as setting it to a null value, as above.
|
||||
echo "uninitialized_variable = $uninitialized_variable"
|
||||
# It still has a null value.
|
||||
|
||||
|
@ -81,7 +88,6 @@ uninitialized_variable=23 # Set it.
|
|||
unset uninitialized_variable # Unset it.
|
||||
echo "uninitialized_variable = $uninitialized_variable"
|
||||
# It still has a null value.
|
||||
|
||||
echo
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/bash
|
||||
# hexconvert.sh: Convert a decimal number to hexadecimal.
|
||||
|
||||
E_NOARGS=65 # Command-line arg missing.
|
||||
BASE=16 # Hexadecimal.
|
||||
|
||||
if [ -z "$1" ]
|
||||
|
|
|
@ -16,6 +16,7 @@ AWKSCRIPT=' { printf( "%3.7f\n", sqrt($1*$1 + $2*$2) ) } '
|
|||
# command(s) / parameters passed to awk
|
||||
|
||||
|
||||
# Now, pipe the parameters to awk.
|
||||
echo -n "Hypotenuse of $1 and $2 = "
|
||||
echo $1 $2 | awk "$AWKSCRIPT"
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
# ^^^^^^^^^^^
|
||||
# Or the domain.name(s) from any e-mail address:
|
||||
# Really_Good_Offer@spammer.biz
|
||||
# ^^^^^^^^^^^
|
||||
#
|
||||
# as the only argument to this script.
|
||||
#(PS: have your Inet connection running)
|
||||
#
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#!/bin/bash
|
||||
# keypress.sh: Detect a user keypress ("hot keyboard").
|
||||
# keypress.sh: Detect a user keypress ("hot keys").
|
||||
|
||||
echo
|
||||
|
||||
old_tty_settings=$(stty -g) # Save old settings.
|
||||
old_tty_settings=$(stty -g) # Save old settings (why?).
|
||||
stty -icanon
|
||||
Keypress=$(head -c1) # or $(dd bs=1 count=1 2> /dev/null)
|
||||
# on non-GNU systems
|
||||
|
|
|
@ -5,14 +5,17 @@ E_NO_ARGS=65
|
|||
|
||||
if [ $# -eq 0 ] # Must have command-line args to demo script.
|
||||
then
|
||||
echo "Invoke this script with one or more command-line arguments."
|
||||
echo "Please invoke this script with one or more command-line arguments."
|
||||
exit $E_NO_ARGS
|
||||
fi
|
||||
|
||||
var01=abcdEFGH28ij
|
||||
|
||||
echo "var01 = ${var01}"
|
||||
echo "Length of var01 = ${#var01}"
|
||||
# Now, let's try embedding a space.
|
||||
var02="abcd EFGH28ij"
|
||||
echo "var02 = ${var02}"
|
||||
echo "Length of var02 = ${#var02}"
|
||||
|
||||
echo "Number of command-line arguments passed to script = ${#@}"
|
||||
echo "Number of command-line arguments passed to script = ${#*}"
|
||||
|
|
|
@ -1,60 +1,55 @@
|
|||
#! /bin/sh
|
||||
#!/bin/bash
|
||||
# letter-count.sh: Counting letter occurrences in a text file.
|
||||
#
|
||||
# Script by nyal (nyal@voila.fr).
|
||||
# Used with permission.
|
||||
# Recommented by document author.
|
||||
# Written by Stefano Palmeri.
|
||||
# Used in ABS Guide with permission.
|
||||
# Slightly modified by document author.
|
||||
|
||||
MINARGS=2 # Script requires at least two arguments.
|
||||
E_BADARGS=65
|
||||
FILE=$1
|
||||
|
||||
let LETTERS=$#-1 # How many letters specified (as command-line args).
|
||||
# (Subtract 1 from number of command line args.)
|
||||
|
||||
|
||||
INIT_TAB_AWK=""
|
||||
# Parameter to initialize awk script.
|
||||
count_case=0
|
||||
FILE_PARSE=$1
|
||||
|
||||
E_PARAMERR=65
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "Usage: letter-count.sh file letters" 2>&1
|
||||
# For example: ./letter-count.sh filename.txt a b c
|
||||
exit $E_PARAMERR # Not enough arguments passed to script.
|
||||
show_help(){
|
||||
echo
|
||||
echo Usage: `basename $0` file letters
|
||||
echo Note: `basename $0` arguments are case sensitive.
|
||||
echo Example: `basename $0` foobar.txt G n U L i N U x.
|
||||
echo
|
||||
}
|
||||
|
||||
if [ ! -f "$1" ] ; then
|
||||
echo "$1: No such file." 2>&1
|
||||
usage # Print usage message and exit.
|
||||
fi
|
||||
# Checks number of arguments.
|
||||
if [ $# -lt $MINARGS ]; then
|
||||
echo
|
||||
echo "Not enough arguments."
|
||||
echo
|
||||
show_help
|
||||
exit $E_BADARGS
|
||||
fi
|
||||
|
||||
if [ -z "$2" ] ; then
|
||||
echo "$2: No letters specified." 2>&1
|
||||
usage
|
||||
fi
|
||||
|
||||
shift # Letters specified.
|
||||
for letter in `echo $@` # For each one . . .
|
||||
do
|
||||
INIT_TAB_AWK="$INIT_TAB_AWK tab_search[${count_case}] = \"$letter\"; final_tab[${count_case}] = 0; "
|
||||
# Pass as parameter to awk script below.
|
||||
count_case=`expr $count_case + 1`
|
||||
# Checks if file exists.
|
||||
if [ ! -f $FILE ]; then
|
||||
echo "File \"$FILE\" does not exist."
|
||||
exit $E_BADARGS
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Counts letter occurrences .
|
||||
for n in `seq $LETTERS`; do
|
||||
shift
|
||||
if [[ `echo -n "$1" | wc -c` -eq 1 ]]; then # Checks arg.
|
||||
echo "$1" -\> `cat $FILE | tr -cd "$1" | wc -c` # Counting.
|
||||
else
|
||||
echo "$1 is not a single char."
|
||||
fi
|
||||
done
|
||||
|
||||
# DEBUG:
|
||||
# echo $INIT_TAB_AWK;
|
||||
|
||||
cat $FILE_PARSE |
|
||||
# Pipe the target file to the following awk script.
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
awk -v tab_search=0 -v final_tab=0 -v tab=0 -v nb_letter=0 -v chara=0 -v chara2=0 \
|
||||
"BEGIN { $INIT_TAB_AWK } \
|
||||
{ split(\$0, tab, \"\"); \
|
||||
for (chara in tab) \
|
||||
{ for (chara2 in tab_search) \
|
||||
{ if (tab_search[chara2] == tab[chara]) { final_tab[chara2]++ } } } } \
|
||||
END { for (chara in final_tab) \
|
||||
{ print tab_search[chara] \" => \" final_tab[chara] } }"
|
||||
# --------------------------------------------------------------------------------
|
||||
# Nothing all that complicated, just . . .
|
||||
#+ for-loops, if-tests, and a couple of specialized functions.
|
||||
|
||||
exit $?
|
||||
|
||||
# This script has exactly the same functionality as letter-count2.sh,
|
||||
#+ but executes faster.
|
||||
# Why?
|
||||
|
|
|
@ -61,7 +61,7 @@ FALSE=1
|
|||
ALIVE=0
|
||||
DEAD=1
|
||||
|
||||
avar= # Global; holds current generation.
|
||||
avar= # Global; holds current generation.
|
||||
generation=0 # Initialize generation count.
|
||||
|
||||
# =================================================================
|
||||
|
@ -276,7 +276,7 @@ done
|
|||
avar=`echo ${array[@]}` # Convert array back to string variable.
|
||||
display "$avar" # Display it.
|
||||
echo; echo
|
||||
echo "Generation $generation -- $alive alive"
|
||||
echo "Generation $generation - $alive alive"
|
||||
|
||||
if [ "$alive" -eq 0 ]
|
||||
then
|
||||
|
@ -312,7 +312,7 @@ echo "======================="
|
|||
Gen0=`echo ${initial[@]}`
|
||||
display "$Gen0" # Display only.
|
||||
echo; echo
|
||||
echo "Generation $generation -- $alive alive"
|
||||
echo "Generation $generation - $alive alive"
|
||||
# -------------------------------------------
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#!/bin/bash
|
||||
# line-number.sh
|
||||
|
||||
# This script echoes itself twice to stdout with its lines numbered.
|
||||
|
||||
# 'nl' sees this as line 3 since it does not number blank lines.
|
||||
# 'cat -n' sees the above line as number 5.
|
||||
# 'nl' sees this as line 4 since it does not number blank lines.
|
||||
# 'cat -n' sees the above line as number 6.
|
||||
|
||||
nl `basename $0`
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ self.show_birthdate # Sat Mar 17 20:13:33 MST 1973
|
|||
|
||||
echo
|
||||
|
||||
# typeset -f
|
||||
# to see the created functions (careful, it scrolls off the page).
|
||||
# typeset -f
|
||||
#+ to see the created functions (careful, it scrolls off the page).
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -24,9 +24,9 @@ echo "username2 = ${username2:-`whoami`}"
|
|||
# Compare to first instance, above.
|
||||
|
||||
|
||||
# =============================================================
|
||||
#
|
||||
|
||||
# Reiterating:
|
||||
# Once again:
|
||||
|
||||
variable=
|
||||
# variable has been declared, but is set to null.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# redir2.sh
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
|
@ -23,12 +24,24 @@ done <"$Filename" # Redirects stdin to file $Filename.
|
|||
|
||||
echo; echo "$count names read"; echo
|
||||
|
||||
exit 0
|
||||
|
||||
# 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.
|
||||
#
|
||||
# Thanks to Heiner Steven for pointing this out.
|
||||
# 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.
|
||||
# (Thanks to Heiner Steven for pointing this out.)
|
||||
|
||||
exit 0
|
||||
# However . . .
|
||||
# Bash *can* sometimes start a subshell in a *redirected* "while" loop.
|
||||
|
||||
abc=hi
|
||||
echo -e "1\n2\n3" | while read l
|
||||
do abc="$l"
|
||||
echo $abc
|
||||
done
|
||||
echo $abc
|
||||
|
||||
# (Thanks, Bruno de Oliveira Schneider, for demonstrating this
|
||||
#+ with the above snippet of code.)
|
||||
|
|
|
@ -32,31 +32,31 @@ head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p'
|
|||
# Assume output up to "sed" --------> |
|
||||
# is 0000000 1198195154\n
|
||||
|
||||
# sed begins reading characters: 0000000 1198195154\n.
|
||||
# Here it finds a newline character,
|
||||
# so it is ready to process the first line (0000000 1198195154).
|
||||
# It looks at its <range><action>s. The first and only one is
|
||||
# sed begins reading characters: 0000000 1198195154\n.
|
||||
# Here it finds a newline character,
|
||||
#+ so it is ready to process the first line (0000000 1198195154).
|
||||
# It looks at its <range><action>s. The first and only one is
|
||||
|
||||
# range action
|
||||
# 1 s/.* //p
|
||||
|
||||
# The line number is in the range, so it executes the action:
|
||||
# tries to substitute the longest string ending with a space in the line
|
||||
# ("0000000 ") with nothing (//), and if it succeeds, prints the result
|
||||
# ("p" is a flag to the "s" command here, this is different from the "p" command).
|
||||
# The line number is in the range, so it executes the action:
|
||||
#+ tries to substitute the longest string ending with a space in the line
|
||||
# ("0000000 ") with nothing (//), and if it succeeds, prints the result
|
||||
# ("p" is a flag to the "s" command here, this is different from the "p" command).
|
||||
|
||||
# sed is now ready to continue reading its input. (Note that before
|
||||
# continuing, if -n option had not been passed, sed would have printed
|
||||
# the line once again).
|
||||
# sed is now ready to continue reading its input. (Note that before
|
||||
#+ continuing, if -n option had not been passed, sed would have printed
|
||||
#+ the line once again).
|
||||
|
||||
# Now, sed reads the remainder of the characters, and finds the end of the file.
|
||||
# It is now ready to process its 2nd line (which is also numbered '$' as
|
||||
# it's the last one).
|
||||
# It sees it is not matched by any <range>, so its job is done.
|
||||
|
||||
# In few word this sed commmand means:
|
||||
# "On the first line only, remove any character up to the right-most space,
|
||||
# then print it."
|
||||
# In few word this sed commmand means:
|
||||
# "On the first line only, remove any character up to the right-most space,
|
||||
#+ then print it."
|
||||
|
||||
# A better way to do this would have been:
|
||||
# sed -e 's/.* //;q'
|
||||
|
@ -68,13 +68,13 @@ head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p'
|
|||
# nothing (matches line) s/.* //
|
||||
# nothing (matches line) q (quit)
|
||||
|
||||
# Here, sed only reads its first line of input.
|
||||
# It performs both actions, and prints the line (substituted) before quitting
|
||||
# (because of the "q" action) since the "-n" option is not passed.
|
||||
# Here, sed only reads its first line of input.
|
||||
# It performs both actions, and prints the line (substituted) before quitting
|
||||
#+ (because of the "q" action) since the "-n" option is not passed.
|
||||
|
||||
# =================================================================== #
|
||||
|
||||
# A simpler altenative to the above 1-line script would be:
|
||||
# An even simpler altenative to the above one-line script would be:
|
||||
# head -c4 /dev/urandom| od -An -tu4
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -18,3 +18,13 @@ do
|
|||
done
|
||||
|
||||
exit 0
|
||||
|
||||
# Exercises:
|
||||
# ---------
|
||||
# 1) Modify this script to take as an optional argument
|
||||
#+ the directory to scan for scripts
|
||||
#+ (rather than just the current working directory).
|
||||
#
|
||||
# 2) As it stands, this script gives "false positives" for
|
||||
#+ Perl, awk, and other scripting language scripts.
|
||||
# Correct this.
|
||||
|
|
|
@ -20,4 +20,7 @@ echo "Temp filename = "$temp_filename""
|
|||
# sh tempfile-name.sh
|
||||
# Temp filename = temp.e19ea
|
||||
|
||||
# Compare this method of generating "unique" filenames
|
||||
#+ with the 'date' method in ex51.sh.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# Written by Rick Boivie.
|
||||
# Used with permission.
|
||||
# This is a revised and simplified version of a script
|
||||
# by Jordi Sanfeliu (and patched by Ian Kjos).
|
||||
#+ by Jordi Sanfeliu (and patched by Ian Kjos).
|
||||
# This script replaces the earlier version used in
|
||||
#+ previous releases of the Advanced Bash Scripting Guide.
|
||||
|
||||
|
@ -35,8 +35,8 @@ do
|
|||
echo "+---$dir" # ==> Display horizontal connector symbol...
|
||||
# ==> and print directory name.
|
||||
numdirs=`expr $numdirs + 1` # ==> Increment directory count.
|
||||
if cd "$dir" ; then # ==> If can move to subdirectory...
|
||||
search `expr $1 + 1` # with recursion ;-)
|
||||
if cd "$dir" ; then # ==> If can move to subdirectory...
|
||||
search `expr $1 + 1` # with recursion ;-)
|
||||
# ==> Function calls itself.
|
||||
cd ..
|
||||
fi
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# unalias.sh
|
||||
|
||||
shopt -s expand_aliases # Enables alias expansion.
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ echo $newestVar
|
|||
|
||||
# Why in the world?
|
||||
# Setting the contents of a string variable containing character
|
||||
#+ sequences that have a meaning to Bash is a general problem in
|
||||
#+ sequences that have a meaning in Bash is a general problem in
|
||||
#+ script programming.
|
||||
#
|
||||
# This problem is now solved in eight lines of code
|
||||
|
|
|
@ -5,7 +5,7 @@ variable=hello # Initialized.
|
|||
echo "variable = $variable"
|
||||
|
||||
unset variable # Unset.
|
||||
# Same effect as variable=
|
||||
# Same effect as: variable=
|
||||
echo "(unset) variable = $variable" # $variable is null.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -11,7 +11,7 @@ then
|
|||
echo "Usage: $0 input-file output-file"
|
||||
exit $E_FILE_ACCESS
|
||||
fi # Will exit with same error
|
||||
#+ even if input file ($1) not specified.
|
||||
#+ even if input file ($1) not specified (why?).
|
||||
|
||||
if [ -z "$2" ]
|
||||
then
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
# ==>
|
||||
# ==> Newer Linux distros (2004 or later) autodetect
|
||||
# ==> and install USB pen drives, and therefore don't need this script.
|
||||
# ==> But, it's still instructive.
|
||||
|
||||
# This code is free software covered by GNU GPL license version 2 or above.
|
||||
# Please refer to http://www.gnu.org/ for the full license text.
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#!/bin/bash
|
||||
# viewdata.sh
|
||||
# Conversion of VIEWDATA.BAT to shell script.
|
||||
|
||||
DATAFILE=/home/bozo/datafiles/book-collection.data
|
||||
ARGNO=1
|
||||
|
||||
# @ECHO OFF Command unnecessary here.
|
||||
# @ECHO OFF Command unnecessary here.
|
||||
|
||||
if [ $# -lt "$ARGNO" ] # IF !%1==! GOTO VIEWDATA
|
||||
then
|
||||
|
@ -15,6 +16,6 @@ fi
|
|||
|
||||
exit 0 # :EXIT0
|
||||
|
||||
# GOTOs, labels, smoke-and-mirrors, and flimflam unnecessary.
|
||||
# The converted script is short, sweet, and clean,
|
||||
# which is more than can be said for the original.
|
||||
# GOTOs, labels, smoke-and-mirrors, and flimflam unnecessary.
|
||||
# The converted script is short, sweet, and clean,
|
||||
#+ which is more than can be said for the original.
|
||||
|
|
|
@ -8,9 +8,9 @@ echo "$var" # '(]\{}$" Doesn't make a difference.
|
|||
echo
|
||||
|
||||
IFS='\'
|
||||
echo $var # '(] {}$" \ converted to space.
|
||||
echo $var # '(] {}$" \ converted to space. Why?
|
||||
echo "$var" # '(]\{}$"
|
||||
|
||||
# Examples above supplied by S.C.
|
||||
# Examples above supplied by Stephane Chazelas.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
# =======================================================================
|
||||
# changelog:
|
||||
|
||||
# 07/02/2005. Fixups by Little Monster.
|
||||
# 02/02/2005. Minor additions by Little Monster.
|
||||
# (See after # +++++++++++ )
|
||||
# 29/01/2005. Minor stylistic edits and cleanups by author of ABS Guide.
|
||||
|
@ -236,50 +237,53 @@ list_func() # Gives the user the option to use the -i option to wget,
|
|||
#+ and a list of URLs.
|
||||
{
|
||||
while [ 1 ]; do
|
||||
echo "Enter the name of the file containing URL's (press q to change your mind)."
|
||||
echo "Enter the name of the file containing URL's (press q to change your
|
||||
mind)."
|
||||
read urlfile
|
||||
if [ ! -e $urlfile ] && [ $urlfile != q ]; then
|
||||
if [ ! -e "$urlfile" ] && [ "$urlfile" != q ]; then
|
||||
# Look for a file, or the quit option.
|
||||
echo "That file does not exist!"
|
||||
elif [ $urlfile = q ]; then # Check quit option.
|
||||
echo "Not using a URL list."
|
||||
elif [ "$urlfile" = q ]; then # Check quit option.
|
||||
echo "Not using a url list."
|
||||
return
|
||||
else
|
||||
echo "Using $urlfile."
|
||||
echo "If you gave me URL's on the command line, I'll use those first."
|
||||
echo "using $urlfile."
|
||||
echo "If you gave me url's on the command line, I'll use those first."
|
||||
# Report wget standard behaviour to the user.
|
||||
lister=" -i $urlfile" # This is what we will pass to wget.
|
||||
lister=" -i $urlfile" # This is what we want to pass to wget.
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
cookie_func() # Give the user the option to use a different cookie file.
|
||||
cookie_func() # Give the user the option to use a different cookie file.
|
||||
{
|
||||
while [ 1 ]; do
|
||||
echo "Change the cookies file. Press return if you don't want to change it."
|
||||
echo "Change the cookies file. Press return if you don't want to change
|
||||
it."
|
||||
read Cookies
|
||||
# NB: this is not the same as Cookie, earlier.
|
||||
# There is an 's' on the end.
|
||||
# Bit like chocolate chips.
|
||||
if [ -z $Cookies ]; then # Escape clause for wusses.
|
||||
if [ -z "$Cookies" ]; then # Escape clause for wusses.
|
||||
return
|
||||
elif [ ! -e $Cookies ]; then
|
||||
echo "File does not exist. Try again." # Keep 'em going . . .
|
||||
elif [ ! -e "$Cookies" ]; then
|
||||
echo "File does not exist. Try again." # Keep em going . . .
|
||||
else
|
||||
CookiesON=" --load-cookies $Cookies" # File is good. Let's use it!
|
||||
CookiesON=" --load-cookies $Cookies" # File is good -- let's use it!
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
run_func()
|
||||
{
|
||||
if [ -z "$OPTARG" ]; then
|
||||
# Test to see if we used the in-line option or the query one.
|
||||
if [ ! -d "$savePath" ]; then # In case directory doesn't exist . . .
|
||||
if [ ! -d "$savePath" ]; then # In case directory doesn't exist . . .
|
||||
echo "$savePath does not appear to exist."
|
||||
echo "Please supply path and filename of saved wget commands:"
|
||||
read newFile
|
||||
|
@ -289,6 +293,7 @@ if [ -z "$OPTARG" ]; then
|
|||
read newFile
|
||||
done
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# if [ -z ( grep wget ${newfile} ) ]; then
|
||||
# Assume they haven't got the right file and bail out.
|
||||
|
@ -301,6 +306,7 @@ if [ -z "$OPTARG" ]; then
|
|||
# If anyone wants to fix it, feel free!
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
filePath="${newFile}"
|
||||
else
|
||||
echo "Save path is $savePath"
|
||||
|
@ -358,7 +364,7 @@ done
|
|||
shift $((OPTIND - 1)) # Do funky magic stuff with $#.
|
||||
|
||||
|
||||
if [ -z "$1" ] && [ ! -z $lister ]; then
|
||||
if [ -z "$1" ] && [ -z "$lister" ]; then
|
||||
# We should be left with at least one URL
|
||||
#+ on the command line, unless a list is
|
||||
#+ being used -- catch empty CL's.
|
||||
|
|
|
@ -11,6 +11,7 @@ do
|
|||
done
|
||||
|
||||
exit 0
|
||||
|
||||
# You may wish to redirect output of this script, like so:
|
||||
# ./what.sh >>whatis.db
|
||||
# or view it a page at a time on stdout,
|
||||
|
|
Loading…
Reference in New Issue