mirror of https://github.com/tLDP/LDP
updated
This commit is contained in:
parent
f83b4dd12e
commit
254dc68d71
|
@ -6,8 +6,96 @@
|
|||
http://personal.riverusers.com/~thegrendel/Change.log
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Release.
|
||||
Version 2.6 'SALAL' release, 03/15/04
|
||||
Version 2.7
|
||||
Mulberry release, 04/18/04
|
||||
|
||||
1) In the "Starting Off With a Sha-Bang" chapter:
|
||||
Added "ex1a.sh" example as a bridge between "ex1.sh" and "ex2.sh"
|
||||
examples.
|
||||
Added a few explanatory notes.
|
||||
Minor revisions to comments in "ex1.sh" and "ex2.sh" examples.
|
||||
Added "$" to variable name in script prolog note.
|
||||
Minor revisions to "Why Shell Programming?" section.
|
||||
|
||||
2) In "Special Characters" chapter:
|
||||
In in-line example at "Control-K" entry, expanded explanation of
|
||||
effect of a vertical tab.
|
||||
(Thank you, Lee Maschmeyer.)
|
||||
Minor rewording at "`" (backticks), "\" (escape), and other entries.
|
||||
|
||||
3) In "Quoting" chapter:
|
||||
Slight rewording of note about certain programs expanding special
|
||||
characters in a quoted string.
|
||||
Dropped word "apparently" from footnote on quoting "!" character.
|
||||
|
||||
4) In "/dev" section of "/dev and /proc" chapter:
|
||||
Added short explanation of Bash's treatment of /dev/tcp/host/port
|
||||
pseudo-device files.
|
||||
Added footnote defining a socket.
|
||||
Added use of /dev/sda1 in mounting a USB flash drive.
|
||||
Added examples of getting the time from a remote network
|
||||
and downloading a URL -- using /dev/tcp.
|
||||
(Thank you, Mark.)
|
||||
|
||||
5) In "/proc" section of "/dev and /proc" chapter:
|
||||
Added "cat /proc/apm" to list of 'proc' examples.
|
||||
Redid first parsing example.
|
||||
|
||||
6) In the "Portability Issues" section of the "Miscellany" chapter:
|
||||
Added discussion of using !#/bin/sh to run scripts.
|
||||
(Thank you, Ian D. Allen.)
|
||||
|
||||
7) In "Assorted Tips" section of "Miscellany" chapter:
|
||||
Added redirecting stderr to stdout in "if-grep" test.
|
||||
(Thank you, Chris Martin.)
|
||||
Added tip about setting PATH and umask at beginning of script.
|
||||
(Thank you, Ian D. Allen.)
|
||||
|
||||
8) In "System and Administrative Commands" chapter:
|
||||
At "ifconfig" entry, added "ifconfig -a" output example.
|
||||
At "hostname" entry, added note about "domainname" and similar
|
||||
commands.
|
||||
At "netstat" entry, added screen output example.
|
||||
|
||||
9) In "Text Processing" section of "External Commands" Chapter:
|
||||
Added comment (suggested modification) to "wf.sh" example.
|
||||
(Thanks, Arun Giridhar.)
|
||||
At "grep" entry, added method of searching for two different patterns,
|
||||
with usage example.
|
||||
|
||||
10) In "Internal Commands and Builtins" chapter:
|
||||
Expanded "ex43.sh" example.
|
||||
|
||||
11) In "Comparison Operators" section of "Tests" chapter:
|
||||
Changed section title.
|
||||
Added brief intro paragraph.
|
||||
At "==" entry, added note and embedded pre-existing example within it.
|
||||
|
||||
12) In "Regular Expressions" chapter:
|
||||
In "Brief Introduction to Regular Expression" Section:
|
||||
Added sidebar with example of testing an RE.
|
||||
In "Globbing" Section:
|
||||
Fixed typo in footnote 1.
|
||||
(Thanks (Asheesh Soni.)
|
||||
|
||||
13) In "Copyright" chapter:
|
||||
Added URL for French translation.
|
||||
|
||||
14) In "Contributed Scripts" appendix:
|
||||
Replaced "tree.sh" script with a simplified version,
|
||||
revised by Rick Boivie.
|
||||
|
||||
15) Added "To Do List" appendix.
|
||||
|
||||
16) Changed all "process id" references to "process ID" to avoid
|
||||
confusion.
|
||||
|
||||
17) Minor cleanups and fixups to various scripts.
|
||||
|
||||
|
||||
|
||||
Version 2.6
|
||||
'SALAL' release, 03/15/04
|
||||
|
||||
1) In "Exit and Exit Status" chapter,
|
||||
Added comment to inline example discussing negation of a 'true' command.
|
||||
|
@ -172,7 +260,7 @@ Version 2.5
|
|||
Noted that GNU tools allow extended REs if escaped.
|
||||
Removed brackets from RE character sets where unnecessary and
|
||||
misleading.
|
||||
In "Globbing Section":
|
||||
In "Globbing" Section:
|
||||
Corrected note about 'echo' performing wildcard expansion.
|
||||
(Thanks, Paulo Marcel Coelho Aragao, for all of the above.)
|
||||
Broke 'echo' filename expansion examples out of main "screen" block.
|
||||
|
@ -483,7 +571,7 @@ Comments: Major release.
|
|||
in the environment (exported).
|
||||
(Thank you, Mr. Fred.)
|
||||
|
||||
9) In "Comparison Operations" section of "Tests" chapter:
|
||||
9) In "Comparison Operators" section of "Tests" chapter:
|
||||
Corrected typos in "str-test.sh" example.
|
||||
(Thank you, Bill Gradwohl.)
|
||||
|
||||
|
@ -2378,7 +2466,7 @@ In "External Filters, Programs, and Commands" section:
|
|||
to Produce This Book".
|
||||
|
||||
89) Added footnote about shell script naming conventions to "Why Shell
|
||||
Programming?" section.
|
||||
Programming?" section of Chapter 1.
|
||||
|
||||
90) Changed all <errorcode> tags to the more appropriate <returnvalue>.
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ NEWFILENAME=$1.unx
|
|||
|
||||
CR='\015' # Carriage return.
|
||||
# 015 is octal ASCII code for CR.
|
||||
# Lines in a DOS text file end in a CR-LF.
|
||||
# Lines in a DOS text file end in CR-LF.
|
||||
# Lines in a UNIX text file end in LF only.
|
||||
|
||||
tr -d $CR < $1 > $NEWFILENAME
|
||||
# Delete CR's and write to new file.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
# crypto-quote.sh: Encrypt quotes
|
||||
|
||||
# Will encrypt famous quotes in a simple monoalphabetic substitution.
|
||||
# Will encrypt famous quotes in a simple monoalphabetic substitution.
|
||||
# The result is similar to the "Crypto Quote" puzzles
|
||||
#+ seen in the Op Ed pages of the Sunday paper.
|
||||
|
||||
|
@ -20,7 +20,7 @@ cat "$@" | tr "a-z" "A-Z" | tr "A-Z" "$key"
|
|||
# Passes non-alphabetic characters through unchanged.
|
||||
|
||||
|
||||
# Try this script with something like
|
||||
# Try this script with something like:
|
||||
# "Nothing so needs reforming as other people's habits."
|
||||
# --Mark Twain
|
||||
#
|
||||
|
|
|
@ -18,6 +18,7 @@ done`
|
|||
|
||||
echo "variable2 = $variable2" # variable2 = 0123456789
|
||||
|
||||
# It's possible to embed a loop within a variable declaration.
|
||||
# Demonstrates that it's possible to embed a loop
|
||||
#+ within a variable declaration.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
# An empty array is not the same as an array with empty elements.
|
||||
|
||||
array0=( first second third )
|
||||
array1=( '' ) # "array1" has one empty element.
|
||||
array2=( ) # No elements... "array2" is empty.
|
||||
array1=( '' ) # "array1" consists of one empty element.
|
||||
array2=( ) # No elements . . . "array2" is empty.
|
||||
|
||||
echo
|
||||
ListArray()
|
||||
|
@ -24,7 +24,7 @@ echo "Length of first element in array1 = ${#array1}"
|
|||
echo "Length of first element in array2 = ${#array2}"
|
||||
echo
|
||||
echo "Number of elements in array0 = ${#array0[*]}" # 3
|
||||
echo "Number of elements in array1 = ${#array1[*]}" # 1 (surprise!)
|
||||
echo "Number of elements in array1 = ${#array1[*]}" # 1 (Surprise!)
|
||||
echo "Number of elements in array2 = ${#array2[*]}" # 0
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ echo "Number of elements in array2 = ${#array2[*]}" # 0
|
|||
|
||||
ListArray
|
||||
|
||||
# Try extending those arrays
|
||||
# Try extending those arrays.
|
||||
|
||||
# Adding an element to an array.
|
||||
array0=( "${array0[@]}" "new1" )
|
||||
|
@ -56,44 +56,44 @@ echo
|
|||
echo "Stack height for array2 = $height"
|
||||
|
||||
# The 'pop' is:
|
||||
unset array2[${#array2[@]}-1] # Arrays are zero based
|
||||
height=${#array2[@]}
|
||||
unset array2[${#array2[@]}-1] # Arrays are zero-based,
|
||||
height=${#array2[@]} #+ which means first element has index 0.
|
||||
echo
|
||||
echo "POP"
|
||||
echo "New stack height for array2 = $height"
|
||||
|
||||
ListArray
|
||||
|
||||
# List only 2nd and 3rd elements of array0
|
||||
from=1 # Zero based numbering
|
||||
# List only 2nd and 3rd elements of array0.
|
||||
from=1 # Zero-based numbering.
|
||||
to=2 #
|
||||
array3=( ${array0[@]:1:2} )
|
||||
echo
|
||||
echo "Elements in array3: ${array3[@]}"
|
||||
|
||||
# Works like a string (array of characters)
|
||||
# Try some other "string" forms
|
||||
# Works like a string (array of characters).
|
||||
# Try some other "string" forms.
|
||||
|
||||
# Replacement
|
||||
# Replacement:
|
||||
array4=( ${array0[@]/second/2nd} )
|
||||
echo
|
||||
echo "Elements in array4: ${array4[@]}"
|
||||
|
||||
# Replace all matching wildcarded string
|
||||
# Replace all matching wildcarded string.
|
||||
array5=( ${array0[@]//new?/old} )
|
||||
echo
|
||||
echo "Elements in array5: ${array5[@]}"
|
||||
|
||||
# Just when you are getting the feel for this...
|
||||
# Just when you are getting the feel for this . . .
|
||||
array6=( ${array0[@]#*new} )
|
||||
echo # This one might surprise you
|
||||
echo # This one might surprise you.
|
||||
echo "Elements in array6: ${array6[@]}"
|
||||
|
||||
array7=( ${array0[@]#new1} )
|
||||
echo # After array6 this should not be a surprise
|
||||
echo # After array6 this should not be a surprise.
|
||||
echo "Elements in array7: ${array7[@]}"
|
||||
|
||||
# Which looks a lot like...
|
||||
# Which looks a lot like . . .
|
||||
array8=( ${array0[@]/new1/} )
|
||||
echo
|
||||
echo "Elements in array8: ${array8[@]}"
|
||||
|
@ -102,9 +102,9 @@ echo "Elements in array8: ${array8[@]}"
|
|||
|
||||
# The string operations are performed on
|
||||
#+ each of the elements in var[@] in succession.
|
||||
# Therefore : BASH supports string vector operations
|
||||
# If the result is a zero length string, that
|
||||
#+ element disappears in the resulting assignment.
|
||||
# Therefore : Bash supports string vector operations
|
||||
#+ if the result is a zero length string,
|
||||
#+ that element disappears in the resulting assignment.
|
||||
|
||||
# Question, are those strings hard or soft quotes?
|
||||
|
||||
|
@ -118,8 +118,8 @@ array10=( ${array0[@]#$zap} )
|
|||
echo
|
||||
echo "Elements in array10: ${array10[@]}"
|
||||
|
||||
# Compare array7 with array10
|
||||
# Compare array8 with array9
|
||||
# Compare array7 with array10.
|
||||
# Compare array8 with array9.
|
||||
|
||||
# Answer: must be soft quotes.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# cleanup
|
||||
# Cleanup
|
||||
# Run as root, of course.
|
||||
|
||||
cd /var/log
|
||||
|
|
|
@ -39,5 +39,5 @@ zcat $1 | most
|
|||
|
||||
|
||||
exit $? # Script returns exit status of pipe.
|
||||
# Actually "exit $?" unnecessary, as the script will, in any case,
|
||||
# Actually "exit $?" is unnecessary, as the script will, in any case,
|
||||
# return the exit status of the last command executed.
|
||||
|
|
|
@ -42,7 +42,7 @@ echo "All the command-line parameters are: "$*""
|
|||
if [ $# -lt "$MINPARAMS" ]
|
||||
then
|
||||
echo
|
||||
echo "Give me at least $MINPARAMS command-line arguments!"
|
||||
echo "This script needs at least $MINPARAMS command-line arguments!"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
#!/bin/bash
|
||||
# cleanup, version 2
|
||||
# Run as root, of course.
|
||||
# Cleanup, version 3
|
||||
|
||||
# Warning:
|
||||
# -------
|
||||
# This script uses quite a number of features that will be explained
|
||||
#+ later on.
|
||||
# By the time you've finished the first half of the book,
|
||||
#+ there should be nothing mysterious about it.
|
||||
|
||||
|
||||
|
||||
LOG_DIR=/var/log
|
||||
ROOT_UID=0 # Only users with $UID 0 have root privileges.
|
||||
|
@ -9,6 +17,7 @@ E_XCD=66 # Can't change directory?
|
|||
E_NOTROOT=67 # Non-root exit error.
|
||||
|
||||
|
||||
# Run as root, of course.
|
||||
if [ "$UID" -ne "$ROOT_UID" ]
|
||||
then
|
||||
echo "Must be root to run this script."
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
#!/bin/bash
|
||||
# List the planets.
|
||||
# Listing the planets.
|
||||
|
||||
for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto
|
||||
do
|
||||
echo $planet
|
||||
echo $planet # Each planet on a separate line.
|
||||
done
|
||||
|
||||
echo
|
||||
|
||||
for planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto"
|
||||
# All planets on same line.
|
||||
# Entire 'list' enclosed in quotes creates a single variable.
|
||||
do
|
||||
echo $planet
|
||||
|
|
|
@ -19,12 +19,12 @@ ls . | xargs -i -t cp ./{} $1
|
|||
# {} is a placeholder for output text.
|
||||
# This is similar to the use of a curly bracket pair in "find."
|
||||
#
|
||||
# List the files (ls),
|
||||
# List the files in current directory (ls .),
|
||||
#+ pass the output of "ls" as arguments to "xargs" (-i -t options),
|
||||
#+ then copy (cp) these arguments ({}) to new directory ($1).
|
||||
#
|
||||
# The net result is the exact equivalent of
|
||||
#+ cp * $1
|
||||
#+ unless any of the filenames has "whitespace" characters.
|
||||
#+ unless any of the filenames has embedded "whitespace" characters.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -13,4 +13,33 @@ echo $y #+ but linefeeds removed.
|
|||
# When LF's not preserved, it may make it easier to parse output,
|
||||
#+ using utilities such as "awk".
|
||||
|
||||
echo
|
||||
echo "==========================================================="
|
||||
echo
|
||||
|
||||
# Now, showing how to "expand" a variable using "eval" . . .
|
||||
|
||||
for i in 1 2 3 4 5; do
|
||||
eval value=$i
|
||||
# value=$i has same effect. The "eval" is not necessary here.
|
||||
# A variable lacking a meta-meaning evaluates to itself --
|
||||
#+ it can't expand to anything other than its literal self.
|
||||
echo $value
|
||||
done
|
||||
|
||||
echo
|
||||
echo "---"
|
||||
echo
|
||||
|
||||
for i in ls df; do
|
||||
value=eval $i
|
||||
# value=$i has an entirely different effect here.
|
||||
# The "eval" evaluates the commands "ls" and "df" . . .
|
||||
# The terms "ls" and "df" have a meta-meaning,
|
||||
#+ since they are interpreted as commands,
|
||||
#+ rather than just character strings.
|
||||
echo $value
|
||||
done
|
||||
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -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?
|
||||
chmod 666 /dev/ttyS3 # Must be 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.
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check some of the system's environmental variables.
|
||||
# Check some of the system's environmental variables.
|
||||
# This is good preventative maintenance.
|
||||
# If, for example, $USER, the name of the person at the console, is not set,
|
||||
#+ the machine will not recognize you.
|
||||
|
||||
|
@ -43,9 +44,12 @@ echo
|
|||
#
|
||||
# echo ${ZZXy23AB?} >/dev/null
|
||||
|
||||
# Compare these methods of checking whether a variable has been set
|
||||
#+ with "set -u" . . .
|
||||
|
||||
|
||||
echo "You will not see this message, because script terminated above."
|
||||
|
||||
echo "You will not see this message, because script already terminated."
|
||||
|
||||
HERE=0
|
||||
exit $HERE # Will *not* exit here.
|
||||
exit $HERE # Will NOT exit here.
|
||||
|
|
|
@ -4,7 +4,7 @@ wall <<zzz23EndOfMessagezzz23
|
|||
E-mail your noontime orders for pizza to the system administrator.
|
||||
(Add an extra dollar for anchovy or mushroom topping.)
|
||||
# Additional message text goes here.
|
||||
# Note: Comment lines printed by 'wall'.
|
||||
# Note: 'wall' prints comment lines.
|
||||
zzz23EndOfMessagezzz23
|
||||
|
||||
# Could have been done more efficiently by
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
badname=`ls | grep ' '`
|
||||
|
||||
# Try this:
|
||||
# echo "$badname"
|
||||
|
||||
rm "$badname"
|
||||
|
|
|
@ -4,49 +4,51 @@
|
|||
|
||||
TRUE=1
|
||||
LOGFILE=/var/log/messages
|
||||
# Note that $LOGFILE must be readable (chmod 644 /var/log/messages).
|
||||
# Note that $LOGFILE must be readable
|
||||
#+ (as root, chmod 644 /var/log/messages).
|
||||
TEMPFILE=temp.$$
|
||||
# Create a "unique" temp file name, using process id of the script.
|
||||
# Create a "unique" temp file name, using process id of the script.
|
||||
KEYWORD=address
|
||||
# At logon, the line "remote IP address xxx.xxx.xxx.xxx"
|
||||
# appended to /var/log/messages.
|
||||
# At logon, the line "remote IP address xxx.xxx.xxx.xxx"
|
||||
# appended to /var/log/messages.
|
||||
ONLINE=22
|
||||
USER_INTERRUPT=13
|
||||
CHECK_LINES=100
|
||||
# How many lines in log file to check.
|
||||
# How many lines in log file to check.
|
||||
|
||||
trap 'rm -f $TEMPFILE; exit $USER_INTERRUPT' TERM INT
|
||||
# Cleans up the temp file if script interrupted by control-c.
|
||||
# Cleans up the temp file if script interrupted by control-c.
|
||||
|
||||
echo
|
||||
|
||||
while [ $TRUE ] #Endless loop.
|
||||
do
|
||||
tail -$CHECK_LINES $LOGFILE> $TEMPFILE
|
||||
# Saves last 100 lines of system log file as temp file.
|
||||
# Necessary, since newer kernels generate many log messages at log on.
|
||||
# Saves last 100 lines of system log file as temp file.
|
||||
# Necessary, since newer kernels generate many log messages at log on.
|
||||
search=`grep $KEYWORD $TEMPFILE`
|
||||
# Checks for presence of the "IP address" phrase,
|
||||
# indicating a successful logon.
|
||||
# Checks for presence of the "IP address" phrase,
|
||||
#+ indicating a successful logon.
|
||||
|
||||
if [ ! -z "$search" ] # Quotes necessary because of possible spaces.
|
||||
if [ ! -z "$search" ] # Quotes necessary because of possible spaces.
|
||||
then
|
||||
echo "On-line"
|
||||
rm -f $TEMPFILE # Clean up temp file.
|
||||
rm -f $TEMPFILE # Clean up temp file.
|
||||
exit $ONLINE
|
||||
else
|
||||
echo -n "." # -n option to echo suppresses newline,
|
||||
# so you get continuous rows of dots.
|
||||
echo -n "." # The -n option to echo suppresses newline,
|
||||
#+ so you get continuous rows of dots.
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
done
|
||||
|
||||
|
||||
# Note: if you change the KEYWORD variable to "Exit",
|
||||
# this script can be used while on-line to check for an unexpected logoff.
|
||||
# Note: if you change the KEYWORD variable to "Exit",
|
||||
#+ this script can be used while on-line
|
||||
#+ to check for an unexpected logoff.
|
||||
|
||||
# Exercise: Change the script, as per the above note,
|
||||
# Exercise: Change the script, per the above note,
|
||||
# and prettify it.
|
||||
|
||||
exit 0
|
||||
|
@ -61,7 +63,7 @@ while true
|
|||
done
|
||||
|
||||
# Problem: Hitting Control-C to terminate this process may be insufficient.
|
||||
# (Dots may keep on echoing.)
|
||||
#+ (Dots may keep on echoing.)
|
||||
# Exercise: Fix this.
|
||||
|
||||
|
||||
|
@ -76,5 +78,5 @@ do echo -n .
|
|||
done
|
||||
echo "On-line"
|
||||
|
||||
# Exercise: Discuss the strengths and weaknesses
|
||||
# of each of these various approaches.
|
||||
# Exercise: Discuss the relative strengths and weaknesses
|
||||
#! of each of these various approaches.
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
#!/bin/bash
|
||||
# param-sub.sh
|
||||
|
||||
# Whether a variable has been declared
|
||||
#+ affects triggering of the default option
|
||||
#+ even if the variable is null.
|
||||
|
||||
username0=
|
||||
# username0 has been declared, but is set to null.
|
||||
|
@ -13,5 +18,6 @@ username2=
|
|||
# username2 has been declared, but is set to null.
|
||||
echo "username2 = ${username2:-`whoami`}"
|
||||
# Will echo because of :- rather than just - in condition test.
|
||||
# Compare to first instance, above.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
# Written by Rick Boivie, and used with permission.
|
||||
# Modifications by document author.
|
||||
|
||||
MINARGS=1 # Script needs at least one argument.
|
||||
MINARGS=1 # Script needs at least one argument.
|
||||
DATAFILE=./phonebook
|
||||
# A data file named "phonebook" must exist.
|
||||
# A data file in current working directory
|
||||
#+ named "phonebook" must exist.
|
||||
PROGNAME=$0
|
||||
E_NOARGS=70 # No arguments error.
|
||||
E_NOARGS=70 # No arguments error.
|
||||
|
||||
if [ $# -lt $MINARGS ]; then
|
||||
echo "Usage: "$PROGNAME" data"
|
||||
|
@ -25,11 +26,11 @@ else
|
|||
fi
|
||||
|
||||
exit 0 # Script exits here.
|
||||
# It's o.k. to put non-hashmarked comments
|
||||
#+ and data after this point.
|
||||
# Therefore, it's o.k. to put
|
||||
#+ non-hashmarked comments and data after this point.
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Sample "phonebook" datafile:
|
||||
Sample "phonebook" datafile:
|
||||
|
||||
John Doe 1555 Main St., Baltimore, MD 21228 (410) 222-3333
|
||||
Mary Moe 9899 Jones Blvd., Warren, NH 03787 (603) 898-3232
|
||||
|
@ -45,5 +46,5 @@ Sam Roe 956 E. 8th St., New York, NY 10009 (212) 444-5678
|
|||
$bash pb.sh Roe Sam
|
||||
Sam Roe 956 E. 8th St., New York, NY 10009 (212) 444-5678
|
||||
|
||||
# When more than one argument passed to script,
|
||||
# When more than one argument is passed to this script,
|
||||
#+ it prints *only* the line(s) containing all the arguments.
|
||||
|
|
|
@ -28,3 +28,7 @@ done
|
|||
echo
|
||||
|
||||
exit 0
|
||||
|
||||
# Exercise:
|
||||
# --------
|
||||
# Modify this script to pretty-print a poem from a text data file.
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
#!/bin/bash
|
||||
# May need to be invoked with #!/bin/bash2 on older machines.
|
||||
#
|
||||
# Random password generator for bash 2.x by Antek Sawicki <tenox@tenox.tc>,
|
||||
# Random password generator for Bash 2.x by Antek Sawicki <tenox@tenox.tc>,
|
||||
# who generously gave permission to the document author to use it here.
|
||||
#
|
||||
# ==> Comments added by document author ==>
|
||||
|
||||
|
||||
MATRIX="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
# ==> Password will consist of alphanumeric characters.
|
||||
LENGTH="8"
|
||||
# ==> May change 'LENGTH' for longer password, of course.
|
||||
# ==> May change 'LENGTH' for longer password.
|
||||
|
||||
|
||||
while [ "${n:=1}" -le "$LENGTH" ]
|
||||
|
@ -23,17 +24,17 @@ do
|
|||
# ==> ${#MATRIX} returns length of array MATRIX.
|
||||
|
||||
# ==> $RANDOM%${#MATRIX} returns random number between 1
|
||||
# ==> and length of MATRIX - 1.
|
||||
# ==> and [length of MATRIX] - 1.
|
||||
|
||||
# ==> ${MATRIX:$(($RANDOM%${#MATRIX})):1}
|
||||
# ==> returns expansion of MATRIX at random position, by length 1.
|
||||
# ==> See {var:pos:len} parameter substitution in Section 3.3.1
|
||||
# ==> and following examples.
|
||||
# ==> See {var:pos:len} parameter substitution in Chapter 9.
|
||||
# ==> and the associated examples.
|
||||
|
||||
# ==> PASS=... simply pastes this result onto previous PASS (concatenation).
|
||||
|
||||
# ==> To visualize this more clearly, uncomment the following line
|
||||
# ==> echo "$PASS"
|
||||
# echo "$PASS"
|
||||
# ==> to see PASS being built up,
|
||||
# ==> one character at a time, each iteration of the loop.
|
||||
|
||||
|
@ -41,6 +42,6 @@ do
|
|||
# ==> Increment 'n' for next pass.
|
||||
done
|
||||
|
||||
echo "$PASS" # ==> Or, redirect to file, as desired.
|
||||
echo "$PASS" # ==> Or, redirect to a file, as desired.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
# ramdisk.sh
|
||||
|
||||
# A "ramdisk" is a segment of system RAM memory
|
||||
#+ that acts as if it were a filesystem.
|
||||
#+ which acts as if it were a filesystem.
|
||||
# Its advantage is very fast access (read/write time).
|
||||
# Disadvantages: volatility, loss of data on reboot or powerdown.
|
||||
# less RAM available to system.
|
||||
#+ less RAM available to system.
|
||||
#
|
||||
# What good is a ramdisk?
|
||||
# Keeping a large dataset, such as a table or dictionary on ramdisk
|
||||
# Of what use is a ramdisk?
|
||||
# Keeping a large dataset, such as a table or dictionary on ramdisk,
|
||||
#+ speeds up data lookup, since memory access is much faster than disk access.
|
||||
|
||||
|
||||
|
@ -33,9 +33,10 @@ then #+ so no error if this script is run
|
|||
fi
|
||||
|
||||
dd if=/dev/zero of=$DEVICE count=$SIZE bs=$BLOCKSIZE # Zero out RAM device.
|
||||
# Why is this necessary?
|
||||
mke2fs $DEVICE # Create an ext2 filesystem on it.
|
||||
mount $DEVICE $MOUNTPT # Mount it.
|
||||
chmod 777 $MOUNTPT # So ordinary user can access ramdisk.
|
||||
chmod 777 $MOUNTPT # Enables ordinary user to access ramdisk.
|
||||
# However, must be root to unmount it.
|
||||
|
||||
echo "\"$MOUNTPT\" now available for use."
|
||||
|
@ -45,7 +46,11 @@ echo "\"$MOUNTPT\" now available for use."
|
|||
#+ on reboot or power loss.
|
||||
# Copy anything you want saved to a regular directory.
|
||||
|
||||
# After reboot, run this script again to set up ramdisk.
|
||||
# After reboot, run this script to again set up ramdisk.
|
||||
# Remounting /mnt/ramdisk without the other steps will not work.
|
||||
|
||||
# Suitably modified, this script can by invoked in /etc/rc.d/rc.local,
|
||||
#+ to set up ramdisk automatically at bootup.
|
||||
# That may be appropriate on, for example, a database server.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -56,9 +56,13 @@ print_result
|
|||
# Keep in mind that RANDOM is a pseudorandom generator,
|
||||
#+ and not a spectacularly good one at that.
|
||||
|
||||
# Randomness is a deep and complex subject.
|
||||
# Sufficiently long "random" sequences may exhibit
|
||||
#+ chaotic and other "non-random" behavior.
|
||||
|
||||
# Exercise (easy):
|
||||
# ---------------
|
||||
# Rewrite this script to flip a coin 1000 times.
|
||||
# Choices are "HEADS" or "TAILS".
|
||||
# Choices are "HEADS" and "TAILS".
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# read-novar.sh
|
||||
|
||||
echo
|
||||
|
||||
|
|
|
@ -1,74 +1,59 @@
|
|||
#!/bin/sh
|
||||
# @(#) tree 1.1 30/11/95 by Jordi Sanfeliu
|
||||
# email: mikaku@fiwix.org
|
||||
#
|
||||
# Initial version: 1.0 30/11/95
|
||||
# Next version : 1.1 24/02/97 Now, with symbolic links
|
||||
# Patch by : Ian Kjos, to support unsearchable dirs
|
||||
# email: beth13@mail.utexas.edu
|
||||
#
|
||||
# Tree is a tool for view the directory tree (obvious :-) )
|
||||
#
|
||||
#!/bin/bash
|
||||
# tree.sh
|
||||
|
||||
# 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).
|
||||
# This script replaces the earlier version used in
|
||||
#+ previous releases of the Advanced Bash Scripting Guide.
|
||||
|
||||
# ==> 'Tree' script used here with the permission of its author, Jordi Sanfeliu.
|
||||
# ==> Comments added by the author of this document.
|
||||
# ==> Argument quoting added.
|
||||
|
||||
|
||||
search () {
|
||||
for dir in `echo *`
|
||||
# ==> `echo *` lists all the files in current working directory, without line breaks.
|
||||
# ==> Similar effect to for dir in *
|
||||
# ==> but "dir in `echo *`" will not handle filenames with blanks.
|
||||
do
|
||||
if [ -d "$dir" ] ; then # ==> If it is a directory (-d)...
|
||||
zz=0 # ==> Temp variable, keeping track of directory level.
|
||||
while [ $zz != $deep ] # Keep track of inner nested loop.
|
||||
do
|
||||
echo -n "| " # ==> Display vertical connector symbol,
|
||||
# ==> with 2 spaces & no line feed in order to indent.
|
||||
zz=`expr $zz + 1` # ==> Increment zz.
|
||||
done
|
||||
if [ -L "$dir" ] ; then # ==> If directory is a symbolic link...
|
||||
echo "+---$dir" `ls -l $dir | sed 's/^.*'$dir' //'`
|
||||
# ==> Display horiz. connector and list directory name, but...
|
||||
# ==> delete date/time part of long listing.
|
||||
else
|
||||
echo "+---$dir" # ==> Display horizontal connector symbol...
|
||||
# ==> and print directory name.
|
||||
if cd "$dir" ; then # ==> If can move to subdirectory...
|
||||
deep=`expr $deep + 1` # ==> Increment depth.
|
||||
search # with recursivity ;-)
|
||||
# ==> Function calls itself.
|
||||
numdirs=`expr $numdirs + 1` # ==> Increment directory count.
|
||||
fi
|
||||
fi
|
||||
for dir in `echo *`
|
||||
# ==> `echo *` lists all the files in current working directory,
|
||||
#+ ==> without line breaks.
|
||||
# ==> Similar effect to for dir in *
|
||||
# ==> but "dir in `echo *`" will not handle filenames with blanks.
|
||||
do
|
||||
if [ -d "$dir" ] ; then # ==> If it is a directory (-d)...
|
||||
zz=0 # ==> Temp variable, keeping track of directory level.
|
||||
while [ $zz != $1 ] # Keep track of inner nested loop.
|
||||
do
|
||||
echo -n "| " # ==> Display vertical connector symbol,
|
||||
# ==> with 2 spaces & no line feed in order to indent.
|
||||
zz=`expr $zz + 1` # ==> Increment zz.
|
||||
done
|
||||
|
||||
if [ -L "$dir" ] ; then # ==> If directory is a symbolic link...
|
||||
echo "+---$dir" `ls -l $dir | sed 's/^.*'$dir' //'`
|
||||
# ==> Display horiz. connector and list directory name, but...
|
||||
# ==> delete date/time part of long listing.
|
||||
else
|
||||
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 ;-)
|
||||
# ==> Function calls itself.
|
||||
cd ..
|
||||
fi
|
||||
done
|
||||
cd .. # ==> Up one directory level.
|
||||
if [ "$deep" ] ; then # ==> If depth = 0 (returns TRUE)...
|
||||
swfi=1 # ==> set flag showing that search is done.
|
||||
fi
|
||||
deep=`expr $deep - 1` # ==> Decrement depth.
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# - Main -
|
||||
if [ $# = 0 ] ; then
|
||||
cd `pwd` # ==> No args to script, then use current working directory.
|
||||
else
|
||||
cd $1 # ==> Otherwise, move to indicated directory.
|
||||
if [ $# != 0 ] ; then
|
||||
cd $1 # move to indicated directory.
|
||||
#else # stay in current directory
|
||||
fi
|
||||
echo "Initial directory = `pwd`"
|
||||
swfi=0 # ==> Search finished flag.
|
||||
deep=0 # ==> Depth of listing.
|
||||
numdirs=0
|
||||
zz=0
|
||||
|
||||
while [ "$swfi" != 1 ] # While flag not set...
|
||||
do
|
||||
search # ==> Call function after initializing variables.
|
||||
done
|
||||
echo "Initial directory = `pwd`"
|
||||
numdirs=0
|
||||
|
||||
search 0
|
||||
echo "Total directories = $numdirs"
|
||||
|
||||
exit 0
|
||||
# ==> Challenge: try to figure out exactly how this script works.
|
||||
|
|
|
@ -33,14 +33,22 @@ sed -e 's/\.//g' -e 's/\,//g' -e 's/ /\
|
|||
#+ change space between words to linefeed,
|
||||
#+ then shift characters to lowercase, and
|
||||
#+ finally prefix occurrence count and sort numerically.
|
||||
|
||||
# Arun Giridhar suggests modifying the above to:
|
||||
# . . . | sort | uniq -c | sort +1 [-f] | sort +0 -nr
|
||||
# This adds a secondary sort key, so instances of
|
||||
#+ equal occurrence are sorted alphabetically.
|
||||
# As he explains it:
|
||||
# "This is effectively a radix sort, first on the
|
||||
#+ least significant column
|
||||
#+ (word or string, optionally case-insensitive)
|
||||
#+ and last on the most significant column (frequency)."
|
||||
########################################################
|
||||
|
||||
exit 0
|
||||
|
||||
# Exercises:
|
||||
# ---------
|
||||
# 1) Add 'sed' commands to filter out other punctuation,
|
||||
#+ such as semicolons.
|
||||
# 2) Modify to also filter out multiple spaces and other whitespace.
|
||||
# 3) Add a secondary sort key, so that instances of equal occurrence
|
||||
#+ are sorted alphabetically.
|
||||
|
||||
exit 0
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue