mirror of https://github.com/tLDP/LDP
updated
This commit is contained in:
parent
98a65dd19c
commit
34aacdcf72
|
@ -6,6 +6,123 @@
|
||||||
http://personal.riverusers.com/~thegrendel/Change.log
|
http://personal.riverusers.com/~thegrendel/Change.log
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Version 3.6
|
||||||
|
Pokeberry release, 08/28/05
|
||||||
|
|
||||||
|
1) In "Special Characters" chapter:
|
||||||
|
At "-" (redirection from/to stdin or stdout [dash]) entry,
|
||||||
|
corrected comments.
|
||||||
|
(Thank you, Frank Wang.)
|
||||||
|
Replaced flawed first example at "brace expansion" entry.
|
||||||
|
Added quoting comment at "whitespace" entry.
|
||||||
|
|
||||||
|
2) In "Operators" subsection of "Operations and Related Topics" chapter:
|
||||||
|
Removed unnecessary "echo" from modulo operator usage example.
|
||||||
|
(Thank you, Pasha Zubkov.)
|
||||||
|
|
||||||
|
3) In "/proc" section of "/dev and /proc" chapter:
|
||||||
|
Added comment to "pid-identifier.sh" example, per Teemu Huovila.
|
||||||
|
(Thanks!)
|
||||||
|
|
||||||
|
4) In "Testing and Branching" section of "Loops and Branches" chapter:
|
||||||
|
Changed description of "case" construct from "equivalent of"
|
||||||
|
to "analog to" "switch" in C/C++.
|
||||||
|
(Thank you, Teemu Huovila.)
|
||||||
|
|
||||||
|
5) In "Communications Commands" section of "External Commands" chapter:
|
||||||
|
Added "rsync" entry.
|
||||||
|
|
||||||
|
6) In "Miscellaneous Commands" section of "External Commands" chapter:
|
||||||
|
Added additional usage example at "jot/seq" entry.
|
||||||
|
|
||||||
|
7) In "Internal Commands and Builtins" chapter:
|
||||||
|
Added "testing 'false'" to "false" entry example.
|
||||||
|
(Thank you, Joe Friedrichsen for the suggestion.)
|
||||||
|
At "getopts" entry, made corrections in description of behavior of
|
||||||
|
$GETOPTS.
|
||||||
|
(Thank you, Pharis Monalo.)
|
||||||
|
At "source" entry, added notes about passing arguments to "sourced"
|
||||||
|
file and using a "return" to pass control back to the calling script.
|
||||||
|
Added "caller" entry.
|
||||||
|
|
||||||
|
8) In "Contributed Scripts" appendix:
|
||||||
|
Made changes to "whx.sh" script.
|
||||||
|
|
||||||
|
9) In "Test Constructs" section of "Tests" chapter:
|
||||||
|
Fixed up "ex.11.sh" example for difference in Bash 3.x behavior.
|
||||||
|
(Thank you, Frank Wang.)
|
||||||
|
|
||||||
|
10) In "Internal Variables" section of "Variables Revisited" chapter:
|
||||||
|
Fixed up comments in "t-out.sh" example to reflect changes
|
||||||
|
in Bash 3.x.
|
||||||
|
(Thank you, Frank Wang.)
|
||||||
|
Fixed up explanation of "anomalous" output given by ${PIPESTATUS[@]}
|
||||||
|
in certain situations.
|
||||||
|
(Thank you, Frank Wang, for providing Chet Ramey's explanation.)
|
||||||
|
|
||||||
|
11) In "Typing Variables" section of "Variables Revisited" chapter:
|
||||||
|
Added caution + example of how "typeset" restricts the scope of a
|
||||||
|
variable.
|
||||||
|
(Thank you, Michael Iatrou.)
|
||||||
|
|
||||||
|
|
||||||
|
12) In "File and Archiving Commands" section of "External Commands" Chapter:
|
||||||
|
At "file" entry, fixed typo (/usrlocal/bin => /usr/local/bin).
|
||||||
|
Fixed error in "strip-comments.sh" example script.
|
||||||
|
(Thank you, Jesse Gough.)
|
||||||
|
|
||||||
|
13) In "Complex Commands" section of "External Commands" Chapter:
|
||||||
|
At "xargs" entry, added extra usage example.
|
||||||
|
At "expr" entry, added example of illegal arithmetic operation.
|
||||||
|
|
||||||
|
14) In "Here Documents" chapter:
|
||||||
|
Added "self-document2.sh" example.
|
||||||
|
|
||||||
|
15) In "$RANDOM" section of "Variables Revisited" chapter:
|
||||||
|
Added Frank Wang's alternative to jipe's example.
|
||||||
|
|
||||||
|
16) In "Quoting" chapter:
|
||||||
|
Split the chapter into introduction and "Quoting Variables" and
|
||||||
|
"Escaping" sections.
|
||||||
|
|
||||||
|
Corrected note about unquoted "grep" . . .
|
||||||
|
Added discussion about quoting correcting echo's appetite for newlines.
|
||||||
|
Clarified explanation of referencing quoted variables
|
||||||
|
and added footnote.
|
||||||
|
Amended tip about double quotes being necessary only to prevent word
|
||||||
|
splitting.
|
||||||
|
(Thank you, Harald Koenig.)
|
||||||
|
|
||||||
|
17) In "Local Variables" section of "Functions" chapter:
|
||||||
|
In footnoted example of a segfaulting recursive function,
|
||||||
|
added an "echo" to properly exercise the function.
|
||||||
|
(Thank you, Dr. Roland Sonnenschein.)
|
||||||
|
|
||||||
|
18) In "Debugging" chapter:
|
||||||
|
At listing of "Tools for debugging non-working scripts,"
|
||||||
|
added list item for "$LINENO" variable and "caller" builtin.
|
||||||
|
|
||||||
|
At "trap" entry, replaced buggy "multiple-processes.sh" example.
|
||||||
|
(Thank you, Tedman Eng.)
|
||||||
|
|
||||||
|
19) In "Copyright" chapter:
|
||||||
|
Updated licensing terms to give the LDP the right to reassign custodianship
|
||||||
|
of the book in the event the author cannot be contacted.
|
||||||
|
|
||||||
|
20) In "Bibliography" section:
|
||||||
|
Added entry for Peter Knowles' booklistgen.sh --
|
||||||
|
Sony Librie booklist generator -- making possible
|
||||||
|
Linux access to this neat e-book reader.
|
||||||
|
|
||||||
|
21) Corrected spelling of the name of contributor Stéphane Chazelas
|
||||||
|
in multiple places.
|
||||||
|
(Thank you, Bertrand Mollinier Toublet, for pointing out these
|
||||||
|
embarrassing typos.)
|
||||||
|
|
||||||
|
22) Various changes and fixups in example scripts.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Version 3.5
|
Version 3.5
|
||||||
Boxberry release, 06/05/05
|
Boxberry release, 06/05/05
|
||||||
|
|
||||||
|
@ -3194,7 +3311,7 @@ In "External Filters, Programs, and Commands" section:
|
||||||
|
|
||||||
99) Fixed other minor typos in the document.
|
99) Fixed other minor typos in the document.
|
||||||
|
|
||||||
100) Stephané Chazelas sent in long lists of corrections and suggestions.
|
100) Stéphane Chazelas sent in long lists of corrections and suggestions.
|
||||||
Bug fixes, improvements, and comments on "ex2.sh" example.
|
Bug fixes, improvements, and comments on "ex2.sh" example.
|
||||||
Bug fixes and improvements to "ex3.sh" example.
|
Bug fixes and improvements to "ex3.sh" example.
|
||||||
Improvement on "ex4.sh", "ex5.sh", and "ex14.sh" examples.
|
Improvement on "ex4.sh", "ex5.sh", and "ex14.sh" examples.
|
||||||
|
|
|
@ -48,9 +48,10 @@ is-spammer.sh (comments on lines 4, 35, and 51)
|
||||||
bashrc (comments on lines 596 and 618)
|
bashrc (comments on lines 596 and 618)
|
||||||
commentblock.sh (lines 4 and 23)
|
commentblock.sh (lines 4 and 23)
|
||||||
self-document.sh (line 14)
|
self-document.sh (line 14)
|
||||||
|
self-document2.sh (line 8)
|
||||||
dev-tcp.sh (line 14)
|
dev-tcp.sh (line 14)
|
||||||
archiveweblogs.sh (comment in line 4)
|
archiveweblogs.sh (comment in line 4)
|
||||||
multiple-processes.sh (line 61)
|
multiple-processes.sh (line 143)
|
||||||
directory-info.sh (lines 36 and 166)
|
directory-info.sh (lines 36 and 166)
|
||||||
catscripts.sh (lines 12 and 21)
|
catscripts.sh (lines 12 and 21)
|
||||||
is_spammer.bash (comments on various lines)
|
is_spammer.bash (comments on various lines)
|
||||||
|
@ -60,4 +61,4 @@ Hash.lib, (comments in lines lines 103 and 116: & --> &)
|
||||||
hash-example.sh (comment in line 3: < --> <, > --> >)
|
hash-example.sh (comment in line 3: < --> <, > --> >)
|
||||||
quote-fetch.sh (comment in line 26: & --> &)
|
quote-fetch.sh (comment in line 26: & --> &)
|
||||||
ftpget.sh (comment in line 28)
|
ftpget.sh (comment in line 28)
|
||||||
whx.sh (comment in line 230)
|
whx.sh (comment in line 259)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,8 +14,13 @@ fi
|
||||||
filename=$1
|
filename=$1
|
||||||
column_number=$2
|
column_number=$2
|
||||||
|
|
||||||
# Passing shell variables to the awk part of the script is a bit tricky.
|
# Passing shell variables to the awk part of the script is a bit tricky.
|
||||||
# See the awk documentation for more details.
|
# One method is to strong-quote the Bash-script variable
|
||||||
|
#+ within the awk script.
|
||||||
|
# $'$BASH_SCRIPT_VAR'
|
||||||
|
# ^ ^
|
||||||
|
# This is done in the embedded awk script below.
|
||||||
|
# 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 ' ..... '
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,11 @@ fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
if /usr/bin/[ -z "$1" # Again, functionally identical to above.
|
|
||||||
# if /usr/bin/[ -z "$1" ] # Works, but gives an error message.
|
if /usr/bin/[ -z "$1" ] # Again, functionally identical to above.
|
||||||
|
# if /usr/bin/[ -z "$1" # Works, but gives an error message.
|
||||||
|
# # Note:
|
||||||
|
# This has been fixed in Bash, version 3.x.
|
||||||
then
|
then
|
||||||
echo "No command-line arguments."
|
echo "No command-line arguments."
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,8 +1,90 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# multiple-processes.sh: Run multiple processes on an SMP box.
|
# parent.sh
|
||||||
|
# Running multiple processes on an SMP box.
|
||||||
|
# Author: Tedman Eng
|
||||||
|
|
||||||
# Script written by Vernia Damiano.
|
# This is the first of two scripts,
|
||||||
# Used with permission.
|
#+ both of which must be present in the current working directory.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LIMIT=$1 # Total number of process to start
|
||||||
|
NUMPROC=4 # Number of concurrent threads (forks?)
|
||||||
|
PROCID=1 # Starting Process ID
|
||||||
|
echo "My PID is $$"
|
||||||
|
|
||||||
|
function start_thread() {
|
||||||
|
if [ $PROCID -le $LIMIT ] ; then
|
||||||
|
./child.sh $PROCID&
|
||||||
|
let "PROCID++"
|
||||||
|
else
|
||||||
|
echo "Limit reached."
|
||||||
|
wait
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
while [ "$NUMPROC" -gt 0 ]; do
|
||||||
|
start_thread;
|
||||||
|
let "NUMPROC--"
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
|
||||||
|
trap "start_thread" SIGRTMIN
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ======== Second script follows ========
|
||||||
|
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
# child.sh
|
||||||
|
# Running multiple processes on an SMP box.
|
||||||
|
# This script is called by parent.sh.
|
||||||
|
# Author: Tedman Eng
|
||||||
|
|
||||||
|
temp=$RANDOM
|
||||||
|
index=$1
|
||||||
|
shift
|
||||||
|
let "temp %= 5"
|
||||||
|
let "temp += 4"
|
||||||
|
echo "Starting $index Time:$temp" "$@"
|
||||||
|
sleep ${temp}
|
||||||
|
echo "Ending $index"
|
||||||
|
kill -s SIGRTMIN $PPID
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
|
||||||
|
# ======================= SCRIPT AUTHOR'S NOTES ======================= #
|
||||||
|
# It's not completely bug free.
|
||||||
|
# I ran it with limit = 500 and after the first few hundred iterations,
|
||||||
|
#+ one of the concurrent threads disappeared!
|
||||||
|
# Not sure if this is collisions from trap signals or something else.
|
||||||
|
# No doubt someone may spot the bug and will be writing
|
||||||
|
#+ . . . in the future.
|
||||||
|
# ===================================================================== #
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
# The following is the original script written by Vernia Damiano.
|
||||||
|
# Unfortunately, it doesn't work properly.
|
||||||
|
#################################################################
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
# Must call script with at least one integer parameter
|
# Must call script with at least one integer parameter
|
||||||
#+ (number of concurrent processes).
|
#+ (number of concurrent processes).
|
||||||
|
@ -24,33 +106,33 @@ shift
|
||||||
PARAMETRI=( "$@" ) # Parameters of each process
|
PARAMETRI=( "$@" ) # Parameters of each process
|
||||||
|
|
||||||
function avvia() {
|
function avvia() {
|
||||||
local temp
|
local temp
|
||||||
local index
|
local index
|
||||||
temp=$RANDOM
|
temp=$RANDOM
|
||||||
index=$1
|
index=$1
|
||||||
shift
|
shift
|
||||||
let "temp %= $TEMPO"
|
let "temp %= $TEMPO"
|
||||||
let "temp += 1"
|
let "temp += 1"
|
||||||
echo "Starting $index Time:$temp" "$@"
|
echo "Starting $index Time:$temp" "$@"
|
||||||
sleep ${temp}
|
sleep ${temp}
|
||||||
echo "Ending $index"
|
echo "Ending $index"
|
||||||
kill -s SIGRTMIN $$
|
kill -s SIGRTMIN $$
|
||||||
}
|
}
|
||||||
|
|
||||||
function parti() {
|
function parti() {
|
||||||
if [ $INDICE -gt 0 ] ; then
|
if [ $INDICE -gt 0 ] ; then
|
||||||
avvia $INDICE "${PARAMETRI[@]}" &
|
avvia $INDICE "${PARAMETRI[@]}" &
|
||||||
let "INDICE--"
|
let "INDICE--"
|
||||||
else
|
else
|
||||||
trap : SIGRTMIN
|
trap : SIGRTMIN
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
trap parti SIGRTMIN
|
trap parti SIGRTMIN
|
||||||
|
|
||||||
while [ "$NUMPROC" -gt 0 ]; do
|
while [ "$NUMPROC" -gt 0 ]; do
|
||||||
parti;
|
parti;
|
||||||
let "NUMPROC--"
|
let "NUMPROC--"
|
||||||
done
|
done
|
||||||
|
|
||||||
wait
|
wait
|
||||||
|
|
|
@ -18,6 +18,10 @@ pidno=$( ps ax | grep $1 | awk '{ print $1 }' | grep $1 )
|
||||||
# Checks for pid in "ps" listing, field #1.
|
# Checks for pid in "ps" listing, field #1.
|
||||||
# Then makes sure it is the actual process, not the process invoked by this script.
|
# Then makes sure it is the actual process, not the process invoked by this script.
|
||||||
# The last "grep $1" filters out this possibility.
|
# The last "grep $1" filters out this possibility.
|
||||||
|
#
|
||||||
|
# pidno=$( ps ax | awk '{ print $1 }' | grep $1 )
|
||||||
|
# also works, as Teemu Huovila, points out.
|
||||||
|
|
||||||
if [ -z "$pidno" ] # If, after all the filtering, the result is a zero-length string,
|
if [ -z "$pidno" ] # If, after all the filtering, the result is a zero-length string,
|
||||||
then # no running process corresponds to the pid given.
|
then # no running process corresponds to the pid given.
|
||||||
echo "No such process running."
|
echo "No such process running."
|
||||||
|
|
|
@ -31,7 +31,7 @@ fi
|
||||||
#--------
|
#--------
|
||||||
sed '
|
sed '
|
||||||
/^\/\*/d
|
/^\/\*/d
|
||||||
/.*\/\*/d
|
/.*\*\//d
|
||||||
' $1
|
' $1
|
||||||
#--------
|
#--------
|
||||||
# Easy to understand if you take several hours to learn sed fundamentals.
|
# Easy to understand if you take several hours to learn sed fundamentals.
|
||||||
|
@ -41,7 +41,7 @@ sed '
|
||||||
#+ case where line of code has a comment following it on same line.
|
#+ case where line of code has a comment following it on same line.
|
||||||
# This is left as a non-trivial exercise.
|
# This is left as a non-trivial exercise.
|
||||||
|
|
||||||
# Also, the above code deletes lines with a "*/" or "/*",
|
# Also, the above code deletes non-comment lines with a "*/" --
|
||||||
#+ not a desirable result.
|
#+ not a desirable result.
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
TIMELIMIT=4 # 4 seconds
|
TIMELIMIT=4 # 4 seconds
|
||||||
|
|
||||||
read -t $TIMELIMIT variable <&1
|
read -t $TIMELIMIT variable <&1
|
||||||
|
# ^^^
|
||||||
|
# In this instance, "<&1" is needed for Bash 1.x and 2.x,
|
||||||
|
# but unnecessary for Bash 3.x.
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
if [ -z "$variable" ]
|
if [ -z "$variable" ] # Is null?
|
||||||
then
|
then
|
||||||
echo "Timed out, variable still unset."
|
echo "Timed out, variable still unset."
|
||||||
else
|
else
|
||||||
|
@ -17,8 +20,3 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
# Exercise for the reader:
|
|
||||||
# -----------------------
|
|
||||||
# Why is the redirection (<&1) necessary in line 8?
|
|
||||||
# What happens if it is omitted?
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
E_BADARGS=65 # Missing command-line arg.
|
E_BADARGS=65 # Missing command-line arg.
|
||||||
E_NOHOST=66 # Host not found.
|
E_NOHOST=66 # Host not found.
|
||||||
E_TIMEOUT=67 # Host lookup timed out.
|
E_TIMEOUT=67 # Host lookup timed out.
|
||||||
|
E_UNDEF=68 # Some other (undefined) error.
|
||||||
HOSTWAIT=10 # Specify up to 10 seconds for host query reply.
|
HOSTWAIT=10 # Specify up to 10 seconds for host query reply.
|
||||||
# The actual wait may be a bit longer.
|
# The actual wait may be a bit longer.
|
||||||
OUTFILE=whois.txt # Output file.
|
OUTFILE=whois.txt # Output file.
|
||||||
|
@ -34,6 +35,8 @@ else
|
||||||
IPADDR="$1" # Command-line arg was IP address.
|
IPADDR="$1" # Command-line arg was IP address.
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo; echo "IP Address is: "$IPADDR""; echo
|
||||||
|
|
||||||
if [ -e "$OUTFILE" ]
|
if [ -e "$OUTFILE" ]
|
||||||
then
|
then
|
||||||
rm -f "$OUTFILE"
|
rm -f "$OUTFILE"
|
||||||
|
@ -42,7 +45,15 @@ fi
|
||||||
|
|
||||||
|
|
||||||
# Sanity checks.
|
# Sanity checks.
|
||||||
# ==============
|
# (This section needs more work.)
|
||||||
|
# ===============================
|
||||||
|
if [ -z "$IPADDR" ]
|
||||||
|
# No response.
|
||||||
|
then
|
||||||
|
echo "Host not found!"
|
||||||
|
exit $E_NOHOST # Bail out.
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ "$IPADDR" =~ "^[;;]" ]]
|
if [[ "$IPADDR" =~ "^[;;]" ]]
|
||||||
# ;; connection timed out; no servers could be reached
|
# ;; connection timed out; no servers could be reached
|
||||||
then
|
then
|
||||||
|
@ -63,11 +74,11 @@ then
|
||||||
echo "Host not found!"
|
echo "Host not found!"
|
||||||
exit $E_NOHOST # Bail out.
|
exit $E_NOHOST # Bail out.
|
||||||
fi
|
fi
|
||||||
# ==============
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ========== Main body of script ==========
|
|
||||||
|
# ======================== Main body of script ========================
|
||||||
|
|
||||||
AFRINICquery() {
|
AFRINICquery() {
|
||||||
# Define the function that queries AFRINIC. Echo a notification to the
|
# Define the function that queries AFRINIC. Echo a notification to the
|
||||||
|
@ -179,9 +190,27 @@ RIPEquery() {
|
||||||
# * octet2 is the second most significant octet
|
# * octet2 is the second most significant octet
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
slash8=`echo $IPADDR | cut -d. -f 1`
|
slash8=`echo $IPADDR | cut -d. -f 1`
|
||||||
|
if [ -z "$slash8" ] # Yet another sanity check.
|
||||||
|
then
|
||||||
|
echo "Undefined error!"
|
||||||
|
exit $E_UNDEF
|
||||||
|
fi
|
||||||
slash16=`echo $IPADDR | cut -d. -f 1-2`
|
slash16=`echo $IPADDR | cut -d. -f 1-2`
|
||||||
|
# ^ Period specified as 'cut" delimiter.
|
||||||
|
if [ -z "$slash16" ]
|
||||||
|
then
|
||||||
|
echo "Undefined error!"
|
||||||
|
exit $E_UNDEF
|
||||||
|
fi
|
||||||
octet2=`echo $slash16 | cut -d. -f 2`
|
octet2=`echo $slash16 | cut -d. -f 2`
|
||||||
|
if [ -z "$octet2" ]
|
||||||
|
then
|
||||||
|
echo "Undefined error!"
|
||||||
|
exit $E_UNDEF
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Check for various odds and ends of reserved space.
|
# Check for various odds and ends of reserved space.
|
||||||
|
@ -241,5 +270,7 @@ exit 0
|
||||||
|
|
||||||
#@ ABS Guide author comments:
|
#@ ABS Guide author comments:
|
||||||
#@ Nothing fancy here, but still a very useful tool for hunting spammers.
|
#@ Nothing fancy here, but still a very useful tool for hunting spammers.
|
||||||
#@ Sure, the script can be cleaned up a bit (exercise for reader),
|
#@ Sure, the script can be cleaned up some, and it's still a bit buggy,
|
||||||
#@+ but still, it's a nice piece of coding by Walter Dnes.
|
#@+ (exercise for reader), but all the same, it's a nice piece of coding
|
||||||
|
#@+ by Walter Dnes.
|
||||||
|
#@ Thank you!
|
||||||
|
|
Loading…
Reference in New Issue