Advanced Shell Script Programming For Business ContinCenter Automation, Part 1 - The Template (2017)
Advanced Shell Script Programming For Business ContinCenter Automation, Part 1 - The Template (2017)
Programming
By
Dana French
Copyright © by Dana French, 2016: All
Rights Reserved
Note to Reader: If you are reading
this book on a portable device, it will
be best viewed in Landscape mode.
Contents
Forward
Introduction
Chapter 1: Business Continuity thru
Data Center Automation
Chapter 2: The Basic Template
Chapter 3: The Intermediate Template
Chapter 4: The Library Template
Chapter 5: Create a Function Library
Chapter 6: The Advanced Template
Chapter 7: Automated Documentation
Chapter 8: The Advanced Shell Script
Chapter 9: Local/ Remote Command
Execution
Chapter 10: Conclusion
Appendix A
Function: my_template01_k93
Appendix B
Function: my_template02_zbksh
Appendix C
Function: my_template03_zbksh
Appendix D
FUNCTION LIBRARY
Function: echo_zbksh
Function: execl_zbksh
Function: find_dot_file_zbksh
Function: stderr_comment_zbksh
Function: stderr_zbksh
Function: stdout_zbksh
Function: verbose_comment_zbksh
Function: wikiAutoLoad_zbksh
Appendix E
Function: my_template04_zbksh
Appendix F
Usage Message: wikiAutoLoad_zbksh
Function: wikiAutoLoad_zbksh
Appendix G
Standalone Shell Script:
my_template05.sh
Function: my_template05_zbksh
Hidden Configuration File:
.my_template05_zbksh.conf
Usage Message File:
.my_template05_zbksh.usagemsg
Documentation File:
.my_template05_zbksh.document
Examples File:
.my_template05_zbksh.example
Standalone Shell Script:
adv_template05.sh
Script Prefix File: .adv_zbksh.prefix
Appendix H
Function: execl_zbksh
Hidden Configuration File:
.execl_zbksh.conf
Hidden Usage Message File:
.execl_zbksh.usagemsg
About the Author
Forward
The materials presented in this book are at the
forefront of a new mentality in Information
Technology Management. This mentality is a
movement away from the interactive
requirements of data center management tools
of the past, and toward a totally automated
environment. This automation includes not only
the deployment and configuration of new and
existing systems, but the ability to generate
documentation instead of writing it. This
automated documentation is generated by the
systems themselves and used for system
support, maintenance, disaster recovery, audit
compliance and response, training, and other
purposes. The point is to eliminate the latency
between system changes, and documentation
updates, the goal being a greater assurance of
business continuity.
Much of the material in this book is technical in
nature, but it is always presented with an eye
toward business continuity. This is to reinforce
the primary objective of this book, which is the
implementation of data center automation as a
mechanism of achieving business continuity.
Introduction
Do you remember when you were in school and
the classes you were taking had titles such as
“Introduction to this...”, “Basic Principles of
that...”? You probably never had a course, class,
or book whose title began with “Advanced...”?
Well, guess what, today is the day!
Please be aware the title of this book does not
begin with “Advanced...” for no reason or just
to draw attention to itself. This is not a book for
beginners to shell scripting. This book assumes
you are already an accomplished writer of shell
scripts, and does not cover the basics or syntax.
This book discusses advanced techniques and
methodologies. To determine if this book is for
you ask yourself the following questions:
Do I know the difference between shell built-
in commands and UNIX commands?
Do I use shell script functions regularly in my
scripts?
Do I use the “getopts” function regularly in
scripts?
Do I use “traps” in my scripts?
Do I know what “positional parameters” are
and how to use them?
Do I know what “variable operators” are and
how to use them?
Do I know the difference between math
operators and string comparison operators?
If you answered “yes” to all of the above
questions, then continue reading, you passed the
test, and you are ready. But be aware that
answering “yes” to the above questions does not
mean you are familiar with the contents of this
book. Most of the topics in the question list
above, will be covered in the first couple of
chapters when you build a template shell script.
And most people reading this book will have
difficulty understanding the first few chapters,
even if they are accomplished script writers.
The topics discussed in this book will include
advanced techniques for writing shell scripts,
automated documentation, managing function
libraries, coding conventions, and several other
techniques oriented around enhancing your
organizations business continuity capabilities.
In fact, by the end of this book, the reader
should realize this is actually an exercise in
implementing Business Continuity using
Advanced Shell Scripting to accomplish the
task.
Chapter 1: Business Continuity thru
Data Center Automation
The entire future of any organization is
dependent upon the system administrator’s
ability to implement business continuity (BC)
plans and actions. BC incorporates a wide range
of technologies under numerous subject matters,
including data center automation. In fact,
automation is a key driving force toward
profitability in a modern data center. Your
competitors are hard at work attempting to
reduce costs and increase performance,
reliability, and consistency by investing in data
center automation. If your competitors achieve
automation first, you and your business will be
left behind struggling to play “catch-up”. If you
work in a for-profit environment, then your data
center operational goals must be oriented
around automation. Whether this automation
utilizes local resources, cloud resources, or a
hybrid combination of both is irrelevant. The
goal must be automation over all resources,
regardless of where they may exist. And the
most important thing to know about automation
is:
Data center automation is largely
performed by shell scripts.
This means that system administrators must be
expert shell scripters, not competent, not
adequate, they must be experts. Virtually
anyone can write a basic shell script, it is not
difficult. The difficulty lies in translating
automation procedures into step-by-step system
commands, and this takes expert level shell
scripting.
In order to understand the importance of shell
scripting in today's modern data center
environment, it is necessary to define some of
the concepts that will be used throughout this
book.
Business Continuity – policies, guidelines,
standards, procedures
Data Center Automation – The strength of
Unix / Linux
Shell Scripting – The mechanism of
Automation
The greatest attribute of UNIX and Linux is the
ability to automate tasks, processes, and
functions. The mechanism by which this
automation occurs, normally begins with, or
consists entirely of, is a shell script. To be really
good at automation, requires system
administrators to be really good at shell
scripting. To be an expert at automation
requires expert shell scripting. Basic knowledge
of shell scripting will only achieve basic
automation (something your competitors can
easily do).
This series of books is intended to provide a
system administrator (who has basic knowledge
of shell programming) with advanced shell
scripting capabilities such that they will be able
to automate any task they wish to perform.
These tasks include automated documentation,
code generators, process scheduling, high
availability fail overs, disaster recovery, etc.
The first book of this series will focus on:
Part One: The Template
Shell Script Functions and Function
Libraries
Multi-Shell Coding
Automated Documentation
Introduction to Local or Remote Execution
Coding
This series of books does not discuss basic or
introductory techniques, features, or concepts.
These books contain “Advanced” concepts and
are not meant for the novice or beginner in Shell
Programming.
This first book will concentrate on a
standardized shell scripting template that can be
used to create every new shell script. It will
provide a starting point at which the advanced
shell programmer can begin, without having to
start from zero every time. The template utilizes
several functions, techniques, and features
which can be customized to accommodate any
requirement.
Numerous concepts and techniques will be
discussed in a series of progressive
improvements to the basic template. These
progressive improvements will start with a
discussion of beginning every script as a shell
script function, and how to determine what type
of function should be defined. The next
discussion will describe the shell function
library, how to create and reference functions
from the library.
The standardized shell script template will
include the following parts and components:
Usage Message
Dynamic Configuration
Signal Traps
Command Line Option Processing
Embedded Documentation
Standardized Variables
◦ TRUE
◦ FALSE
◦ VERBOSE
◦ VERYVERB
Where:
-v = Verbose mode - displays my_template01_k93 function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
CFILE=~/.my_template01_k93.conf
return 0
}
####################################################
return 0
$
Since the command shown above is executed
with no command line arguments, nothing was
displayed. Run it again with the “-?” command
line argument to cause it to display the usage
message:
$ ./my_template01_k93 -?
Program my_template01_k93
Where:
-v = Verbose mode - displays my_template01_k93
function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
"AutoContent" enabled
TRUE="0"
FALSE="1"
####
#### Extract the "shebang" line from the beginning of the script
####
#### Test the "shebang" line to determine what shell interpreter is
specified
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
####
#### Modify the commands and script according to the shell interpreter
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" &&
emulate ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on
extended globbing
####
#### Call the script function to begin processing
my_template02_zbksh "${@}"
####
#### Test the "shebang" line to determine what shell interpreter is
specified
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" &&
emulate ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on
extended globbing
my_template02_zbksh "${@}"
Now go back to the top of the Intermediate
template script and step thru the changes in each
function. At the top of the script observe the
usage message function which displays the
instructions for executing the shell script. It
provides a description of the function, lists
command line options, syntax, and any other
information the function programmer thinks is
relevant to the shell script programmer. You will
see some differences between the Basic and
Intermediate versions.
Basic Template Version:
function usagemsg_my_template01_k93 {
print "
Program: my_template01_k93
Where:
-v = Verbose mode - displays my_template01_k93 function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Author: Your Name ([email protected])
\"AutoContent\" enabled
"
}
${CMD_ECHO} "
Place a brief description ( < 255 chars ) of your shell
function here.
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-v = Verbose mode - displays my_template02_zbksh function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
\"AutoContent\" enabled
\"Multi-Shell\" enabled
"
}
CFILE=~/.my_template01_k93.conf
if [[ -f ${CFILE} ]]
then
(( VERBOSE == TRUE )) && cat ${CFILE}
. ${CFILE}
fi
return 0
}
CMD_ECHO="${GBL_ECHO:-echo -e }"
if [[ -f ${MYT_CFILE} ]]
then
(( VERBOSE == TRUE )) && cat ${MYT_CFILE}
. ${MYT_CFILE}
fi
return 0
}
The variable CMD_ECHO is again initialized
inside the Intermediate template configuration
function using the value of GBL_ECHO. And
in this version, the configuration file name is
assembled from the value of the first command
line parameter followed by the suffix “.conf”.
Before using the value of the first command line
parameter, it is tested to verify it contains a non-
null value. Also the first command line
parameter is tested to verify the value
corresponds to a file that exists, and it is a
regular file.
The purpose of the configuration function in the
Intermediate template is the same as in the
Basic template, which is to provide a dynamic
mechanism of configuring the shell script
function. It executes a configuration file which
is assumed to contain shell code. Usually this
file contains shell variable definitions, however
it may contain any shell code desired, including
references to outside functions, applications, or
utilities.
Again, this Intermediate template configuration
function contains embedded documentation
identified as comments beginning with 4 #'s
followed by a space (#### ).
The next section of the Intermediate template
script contains the commands which comprise
the primary purpose of the script. This is a
function named “my_template02_zbksh” and is
defined using the Korn Shell style definition
syntax. One of the features of using this syntax
is the shell script programmer will have the
ability to assign local variables inside the
function. However if this same script is
executed as a Bash script, all variables become
global variables regardless of the function
definition syntax or use of the “typeset” built-in
command.
NOTE: In Korn Shell 93, if a variable
is initialized inside a Korn Shell style
function using the ‘typeset” built-in
command, the variable becomes a local
variable to the function.
It is normally best practice to initialize all local
variables at the beginning of each function,
however some shell interpreters do not support
local variable definitions. To accommodate
these shell interpreters, it is best practice to use
variable names that are unique to each function
for local variables. This can be observed in the
variable initialization of the
“my_template02_zbksh” function:
typeset TRUE="${TRUE:-0}"
typeset FALSE="${FALSE:-1}"
typeset VERBOSE="${VERBOSE:-${FALSE}}"
typeset VERYVERB="${VERYVERB:-${FALSE}}"
typeset OPTIND="1"
typeset CMD_ECHO="${GBL_ECHO:-echo -e }"
typeset MYT_PROGRAM="my_template02_zbksh"
typeset MYT_VERSION="1.0"
typeset MYT_TGGLEUP="${FALSE}"
typeset MYT_TGGLELO="${FALSE}"
typeset MYT_ARGVALU=""
####################################################
if (( VERBOSE == TRUE ))
then
for MYT_ARGVALU in "${@}"
do
${CMD_ECHO} "# Command Line Arg..: ${MYT_ARGVALU}"
done
fi
####################################################
if (( ${#@} > 0 ))
then
MYT_MSG="${@}"
fi
if [[ "_${MYT_MSG}" != "_" ]]
then
(( MYT_TGGLEUP == TRUE )) && typeset -u
MYT_MSG="${MYT_MSG}"
(( MYT_TGGLELO == TRUE )) && typeset -l
MYT_MSG="${MYT_MSG}"
for i in “${ARRY[@]}”
do
print “${i}”
done
IDX=”0”
while read VALUE
do
ARRY[IDX++]=”${VALUE}”
done < /tmp/tmp${$}.out
rm –f /tmp/tmp${$}.out
for i in “${ARRY[@]}”
do
echo “${i}”
done
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-v = Verbose mode - displays my_template02_zbksh function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
"AutoContent" enabled
"Multi-Shell" enabled
$ ./my_template02.zbksh -l
hello world!
$ ./my_template02.zbksh –u -l
# ERROR: Do not specify both upper and lower case conversion
together
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-v = Verbose mode - displays my_template02_zbksh function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
"AutoContent" enabled
"Multi-Shell" enabled
Now change the SHEBANG line to bash, and
re-run the script commands. The results should
be the same.
vi my_template02_zbksh
#!/bin/bash
#!/usr/bin/ksh93
#!/bin/zsh
####################################################
####
#### This script will run in KornShell93, Zshell, or Bash, all you need
to do
#### is put the desired "shebang" line at the top of the script.
####
####################################################
…
…
…
:wq
$ ./my_template02.zbksh -u
HELLO WORLD!
$ ./my_template02.zbksh -l
hello world!
$ ./my_template02.zbksh –u -l
# ERROR: Do not specify both upper and lower case conversion
together
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-v = Verbose mode - displays my_template02_zbksh function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
"AutoContent" enabled
"Multi-Shell" enabled
####
#### Identify the function library directories to search
#### in the FPATH environment variable
FPATH=~/functions/adv_zbksh:~/functions:/usr/local/functions
export FPATH
####
#### Define the values for TRUE and FALSE,
#### In shell think, TRUE is zero (0) and FALSE is non-zero.
TRUE="0"
FALSE="1"
####
#### Extract the "shebang" line from the beginning of the script
####
#### Test the "shebang" line to determine what shell interpreter is
specified
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
####
#### Modify the shell specific commands and script according to the
shell interpreter
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" &&
emulate ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on
extended globbing
####
#### For those shell interpreters that do not directly support function
libraries,
#### cache all the *_zbksh functions found in the FPATH directories.
####
if [[ "_${SHCODE}" == "_zshell" ]] ||
[[ "_${SHCODE}" == "_bash" ]]
then
#### Loop thru each directory in the FPATH list using a colon (:)
delimeter.
#### Process each directory in reverse order to simulate results of
#### searching the FPATH directory.
IFS=":"
FDIRS=( ${FPATH} )
IFS=$' \t\n'
END=${#FDIRS[@]}
for (( IDX=END-1; IDX>=0; --IDX ))
do
FDIR="${FDIRS[${IDX}]}"
#### Gather a list of functions ending in *_zbksh from the directory and
loop
#### thru each file using a “for†loop.
fi
####
#### Call the script function to begin processing
my_template03_zbksh "${@}"
#### Loop thru each directory in the FPATH list using a colon (:)
delimeter.
#### Process each directory in reverse order to simulate results of
#### searching the FPATH directory.
IFS=":"
FDIRS=( ${FPATH} )
IFS=$' \t\n'
END=${#FDIRS[@]}
for (( IDX=END-1; IDX>=0; --IDX ))
do
FDIR="${FDIRS[${IDX}]}"
#### Gather a list of functions ending in *_zbksh from the directory and
loop
#### thru each file using a “for†loop.
IFS=$' \t\n'
fi
my_template03_zbksh "${@}"
${CMD_ECHO} "
Place a brief description ( < 255 chars ) of your shell
function here.
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-v = Verbose mode - displays my_template02_zbksh function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
\"AutoContent\" enabled
\"Multi-Shell\" enabled
"
}
stderr_zbksh ""
stderr_zbksh "${1:+Program: ${1}}${2:+ Version: ${2}}"
stderr_zbksh ""
stderr_zbksh "Place a brief description ( < 255 chars ) of your shell"
stderr_zbksh "function here."
stderr_zbksh ""
stderr_zbksh "Usage: ${1##*/} [-?vV] [-u] [-l]"
stderr_zbksh ""
stderr_zbksh " Where:"
stderr_zbksh " -u = Convert command line arguments to upper case"
stderr_zbksh " -l = Convert command line arguments to lower case"
stderr_zbksh " -v = Verbose mode - displays function info"
stderr_zbksh " -V = Very Verbose Mode - debug output displayed"
stderr_zbksh " -? = Help - display this message"
stderr_zbksh ""
stderr_zbksh "Author: Your Name ([email protected])"
stderr_zbksh ""
stderr_zbksh "\"AutoContent\" enabled"
stderr_zbksh "\"Multi-Shell\" enabled"
stderr_zbksh ""
CMD_ECHO="${GBL_ECHO:-echo -e }"
if [[ -f ${MYT_CFILE} ]]
then
(( VERBOSE == TRUE )) && cat ${MYT_CFILE}
. ${MYT_CFILE}
fi
return 0
}
if [[ -f ${MYT_CFILE} ]]
then
(( VERBOSE == TRUE )) && cat ${MYT_CFILE}
. ${MYT_CFILE}
fi
return 0
}
configure_my_template03_zbksh "${MYT_PROGRAM}"
####################################################
####################################################
if [[ "_${MYT_MSG}" != "_" ]]
then
(( MYT_TGGLEUP == TRUE )) && typeset -u
MYT_MSG="${MYT_MSG}"
(( MYT_TGGLELO == TRUE )) && typeset -l
MYT_MSG="${MYT_MSG}"
IFS=":"
FDIRS=( ${FPATH} )
IFS=$' \t\n'
END=${#FDIRS[@]}
for (( IDX=END-1; IDX>=0; --IDX ))
do
FDIR="${FDIRS[${IDX}]}"
#### Gather a list of functions ending in *_zbksh from the directory and
loop
#### thru each file using a "for"loop.
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-v = Verbose mode - displays my_template02_zbksh function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
"AutoContent" enabled
"Multi-Shell" enabled
$ ./my_template03_zbksh -l
hello world!
$ ./my_template03_zbksh -u -l
# ERROR: Do not specify both upper and lower case conversion
together
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-v = Verbose mode - displays my_template02_zbksh function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
"AutoContent" enabled
"Multi-Shell" enabled
$ ./my_template03_zbksh -u
HELLO WORLD!
$ ./my_template03_zbksh -l
hello world!
$ ./my_template03_zbksh -u -l
# ERROR: Do not specify both upper and lower case conversion
together
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-v = Verbose mode - displays my_template02_zbksh function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Author: Your Name ([email protected])
"AutoContent" enabled
"Multi-Shell" enabled
####################################################
if (( DOT_RECURS == DOT_TRUE ))
then
DOT_RECURS="${DOT_FALSE}"
find_dot_file_zbksh -f "find_dot_file_zbksh" -a "configure"
else
DOT_RECURS="${DOT_TRUE}"
return 0
fi
####################################################
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
####################################################
The option verification section tests the user
specified command line arguments to verify
they conform to acceptable values. In this
version of the function, the “action” specified by
the script programmer must be one of the
following literal values (upper or lower case):
configure
usagemsg
document
example
####################################################
####
#### Check the command line arguments to verify they are valid values
and that all
#### necessary information was specified.
####
if [[ "_${DOT_FUNCNAME}" == "_" ]]
then
# verbose_comment_zbksh -v "${DOT_VERBOSE}" -c "ERROR:
Function Name not specified"
return 10
fi
if [[ "_${DOT_ACTION}" != _[Cc][Oo][Nn][Ff][Ii][Gg][Uu][Rr][Ee]
]] &&
[[ "_${DOT_ACTION}" != _[Uu][Ss][Aa][Gg][Ee][Mm][Ss][Gg]
]] &&
[[ "_${DOT_ACTION}" == _[Dd][Oo][Cc][Uu][Mm][Ee][Nn]
[Tt] ]] &&
[[ "_${DOT_ACTION}" == _[Ee][Xx][Aa][Mm][Pp][Ll][Ee]
]]
then
stderr_comment_zbksh -p "ERROR: Invalid Action Specified" -a
"${DOT_ACTION}"
find_dot_file_zbksh -f "find_dot_file_zbksh" -a "usagemsg"
return 11
fi
####################################################
####
#### Display some DOT_PROGRAM info and the command line
arguments specified
#### if "DOT_VERBOSE" mode was specified.
####
####################################################
####
####
####
DOT_RETCODE="0"
####################################################
#### Define the possible directory locations for the "dot" files in the
FPATH directories.
IDX="0"
IFS=$': \t\n'
for DIR in ${FPATH}
do
DOT_FPATHS[IDX++]="${DIR}"
done
IFS=$' \t\n'
####################################################
#### Define the possible directory locations for the "dot" files under the
users HOME.
#### typeset DOT_HOMES[0]=~
#### typeset DOT_HOMES[1]=~/.adv_zbksh
#### typeset DOT_HOMES[2]=~/adv_zbksh
#### typeset DOT_HOMES[3]=~/functions/adv_zbksh
#### typeset DOT_HOMES[4]=~/functions
IDX="0"
DOT_HOMES[IDX++]=~
DOT_HOMES[IDX++]=~/.adv_zbksh
DOT_HOMES[IDX++]=~/adv_zbksh
DOT_HOMES[IDX++]=~/functions/adv_zbksh
DOT_HOMES[IDX++]=~/functions
#### Define the possible directory locations for the "dot" files under
/usr/local.
IDX="0"
DOT_LOCALS[IDX++]="/usr/local/adv_zbksh"
DOT_LOCALS[IDX++]="/usr/local/functions/adv_zbksh"
DOT_LOCALS[IDX++]="/usr/local/functions"
DOT_LOCALS[IDX++]="/usr/local/scripts/adv_zbksh"
DOT_LOCALS[IDX++]="/usr/local/scripts"
#### Define the possible directory locations for the "dot" files under
MAN pages.
[[ "_${DOT_ACTION}" == _[Cc][Oo][Nn][Ff][Ii][Gg][Uu][Rr][Ee]
]] && DOT_EXTENSION=".conf"
[[ "_${DOT_ACTION}" == _[Uu][Ss][Aa][Gg][Ee][Mm][Ss][Gg]
]] && DOT_EXTENSION=".usagemsg"
[[ "_${DOT_ACTION}" == _[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt]
]] && DOT_EXTENSION=".usagemsg"
[[ "_${DOT_ACTION}" == _[Ee][Xx][Aa][Mm][Pp][Ll][Ee] ]]
&& DOT_EXTENSION=".usagemsg"
#### Loop through each of the directory locations searching for the first
occurrence of
#### a matching "dot" file. The directories are search in order of
HOMES, LOCALS, MANS.
#### The first "dot" file found cause the loop to break.
DOT_EXTFILE="${DOT_DIR}/.${DOT_FUNCNAME}${DOT_EXTENSION}"
# verbose_comment_zbksh -v "${DOT_VERBOSE}" -p "External
File Found" -a "${DOT_EXTFILE}"
break
fi
done
If the user specified the command line “action”
argument as the literal value of “configure”,
then execute the hidden file corresponding with
the function name and extension “.conf”
(${DOT_EXTFILE}) as a “dot” script in the
current shell environment.
#### If an external dot file exists, and the action is "configure", then
#### execute the file as a "dot" script in the current environment
IFS=$' \t\n'
OPTIND="1"
return 0
}
####
#### ####################################################
# MYT_PROGRAM="my_template04_zbksh"
# VERSION="1.0"
MYT_MSG="Hello World!"
OPTIND="1"
while getopts ":vVulDE" OPTION
do
case "${OPTION}" in
'u') MYT_TGGLEUP="${TRUE}";;
'l') MYT_TGGLELO="${TRUE}";;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
'D') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "document"
&& return 4;;
'E') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "example"
&& return 5;;
'?') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "usagemsg"
&& return 1 ;;
':') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "usagemsg"
&& return 2 ;;
'#') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "usagemsg"
&& return 3 ;;
esac
done
####################################################
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-D = Generate Documentation
-E = Execute Examples in Usagemsg
-v = Verbose mode - displays function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Example Usage:
my_template04_zbksh -v -u
my_template04_zbksh -v -l
\"AutoContent\" enabled
\"Multi-Shell\" enabled
#### Your shell function should perform its specific work here.
#### All work performed by your shell function should be coded
#### within this section of the function. This does not mean that
#### your function should be called from here, it means the shell
#### code that performs the work of your function should be
#### incorporated into the body of this function. This should
#### become your function.
#### Extract the "shebang" line from the beginning of the script
#### Modify the shell specific commands and script according to the
shell interpreter
#### For those shell interpreters that do not directly support function
libraries,
#### cache all the *_zbksh functions found in the FPATH directories.
#### Loop thru each directory in the FPATH list using a colon (:)
delimeter.
#### Process each directory in reverse order to simulate results of
#### searching the FPATH directory.
#### Gather a list of functions ending in *_zbksh from the directory and
loop
#### thru each file using a “for†loop.
FPATH="."
export FPATH
echo
"####################################################"
my_template04_zbksh -D > .my_template04_zbksh.document 2>&1
my_template04_zbksh -E > .my_template04_zbksh.example 2>&1
FPATH="."
export FPATH
# PROGRAM="wikiAutoLoad_zbksh"
# VERSION="2.0"
# WAL_WIKIUSER="WikiSysop"
# WAL_WIKIPASS="abcd1234"
# WAL_APIURL="http://127.0.0.1/wiki/api.php"
# WAL_PAGETITLE=""
# WAL_CATEGORIES="Upload"
FPATH="."
export FPATH
for i in .*.document
do
wikiAutoLoad_zbksh -v "${i}"
done
The above script assumes it is being executed
from the function library directory. It searches
for all hidden files with a “.document” suffix
and calls the function “wikiAutoLoad_zbksh”
to upload each file.
Additional command line options can be
provided such as the Page Title and Category.
The default page title is the file name of the
content being uploaded. The default category is
“upload”.
Another recommendation regarding embedded
comments is to use “Grutatxt” formatting. This
is a text markup style that can be easily
converted between varieties of formats
including HTML. This allows the script
programmer to use a single formatting style to
support numerous documentation requirements.
The Grutatxt Perl module can be downloaded
from the Internet. There is also an Advanced
Shell Function called “txt2html_zbksh” which
will convert Grutatxt formatted text to HTML.
This function may also be downloaded from the
Internet and will be discussed in a future book
of this series.
This concept of automated documentation is not
limited to shell scripts. It can be easily
implemented across a wide variety of script and
compiled languages. It simply requires an
enterprise wide mentality of Business
Continuity and Data Center Automation.
Chapter 8: The Advanced Shell
Script
If you have made it this far, congratulations! It
has been a long road to get to this point, but this
chapter is the payoff.
Here will be discussed externalizing all
functions to the Function Library, and
minimizing the standalone portions of a script
using a standardized/customized “dot” file. To
begin this discussion, review the various
components of the Advanced Function
Template:
Multi-Shell Interpreter Shebang Line
Korn Shell or POSIX Style Function
declaration
◦ Local variables can exist in Korn Shell
Functions
◦ Global variables in POSIX Functions
Variable Initialization
Dynamic Configuration File
Command Line Option processing
Command Line Argument Verification
Display Function Configuration
Command Processing specific to Functions
External Usage Message File
External Configuration File
External Standalone Script
FPATH=~/functions/adv_zbksh:~/functions:/usr/local/functions
export FPATH
Any additional global variables are initialized
next, including the values of TRUE and
FALSE. These variables are used by the
Advanced Functions to test numerous
conditions and must be defined in the
standalone shell script:
####
#### Define the values for TRUE and FALSE,
#### In shell think, TRUE is zero (0) and FALSE is non-zero.
TRUE="0"
FALSE="1"
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" &&
emulate ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on
extended globbing
if [[ "_${SHCODE}" == "_zshell" ]] ||
[[ "_${SHCODE}" == "_bash" ]]
then
#### Loop thru each directory in the FPATH list using a colon (:)
delimeter.
#### Process each directory in reverse order to simulate results of
#### searching the FPATH directory.
IFS=":"
FDIRS=( ${FPATH} )
IFS=$' \t\n'
END=${#FDIRS[@]}
for (( IDX=END-1; IDX>=0; --IDX ))
do
FDIR="${FDIRS[${IDX}]}"
#### Gather a list of functions ending in *_zbksh from the directory and
loop
#### thru each file using a “for†loop.
IFS=$' \t\n'
fi
my_template05_zbksh "${@}"
# MYT_PROGRAM="my_template05_zbksh"
# VERSION="1.0"
MYT_MSG="Hello World!"
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-D = Generate Documentation
-E = Execute Examples in Usagemsg
-v = Verbose mode - displays function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Example Usage:
my_template05_zbksh -v -u
my_template05_zbksh -v -l
"AutoContent" enabled
"Multi-Shell" enabled
$ ./my_template05.sh -l
hello world!
$ ./my_template05.sh -u -l
# ERROR: Do not specify both upper and lower case conversion
together
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-D = Generate Documentation
-E = Execute Examples in Usagemsg
-v = Verbose mode - displays function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Example Usage:
my_template05_zbksh -v -u
my_template05_zbksh -v -l
"AutoContent" enabled
"Multi-Shell" enabled
$ ./my_template05.sh -u
HELLO WORLD!
$ ./my_template05.sh -l
hello world!
$ ./my_template05.sh -u -l
# ERROR: Do not specify both upper and lower case conversion
together
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-D = Generate Documentation
-E = Execute Examples in Usagemsg
-v = Verbose mode - displays function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Example Usage:
my_template05_zbksh -v -u
my_template05_zbksh -v -l
"AutoContent" enabled
"Multi-Shell" enabled
####
#### Extract the "shebang" line from the beginning of the script
####
#### Identify the function library directories to search
#### in the FPATH environment variable
FPATH=~/functions/adv_zbksh:~/functions:/usr/local/functions
export FPATH
if [[ -f ./.adv_zbksh.prefix ]]
then . ./.adv_zbksh.prefix
elif [[ -f ~/.adv_zbksh.prefix ]]
then . ~/.adv_zbksh.prefix
fi
####
#### Call the script function to begin processing
my_template05_zbksh "${@}"
TRUE="0"
FALSE="1"
# ####
# #### Extract the "shebang" line from the beginning of the script
#
# read SHEBANG < "${0}"
# export SHEBANG
#
####
#### Test the "shebang" line to determine what shell interpreter is
specified
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
####
#### Modify the shell specific commands and script according to the
shell interpreter
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" &&
emulate ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on
extended globbing
####
#### For those shell interpreters that do not directly support function
libraries,
#### cache all the *_zbksh functions found in the FPATH directories.
####
if [[ "_${SHCODE}" == "_zshell" ]] ||
[[ "_${SHCODE}" == "_bash" ]]
then
#### Loop thru each directory in the FPATH list using a colon (:)
delimeter.
#### Process each directory in reverse order to simulate results of
#### searching the FPATH directory.
IFS=":"
FDIRS=( ${FPATH} )
IFS=$' \t\n'
END=${#FDIRS[@]}
for (( IDX=END-1; IDX>=0; --IDX ))
do
FDIR="${FDIRS[${IDX}]}"
#### Gather a list of functions ending in *_zbksh from the directory and
loop
#### thru each file using a “for†loop.
IFS=$' \t\n'
fi
# MYT_PROGRAM="my_template05_zbksh"
# VERSION="1.0"
MYT_MSG="Hello World!"
Verify the command line option “-?” displays
the usage message as seen previously:
$ ./adv_template05.sh -?
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-D = Generate Documentation
-E = Execute Examples in Usagemsg
-v = Verbose mode - displays function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Example Usage:
my_template05_zbksh -v -u
my_template05_zbksh -v -l
"AutoContent" enabled
"Multi-Shell" enabled
$ ./adv_template05.sh -l
hello world!
$ ./adv_template05.sh -u -l
# ERROR: Do not specify both upper and lower case conversion
together
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-D = Generate Documentation
-E = Execute Examples in Usagemsg
-v = Verbose mode - displays function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Example Usage:
my_template05_zbksh -v -u
my_template05_zbksh -v -l
$ ./adv_template05.sh -u
HELLO WORLD!
$ ./adv_template05.sh -l
hello world!
$ ./adv_template05.sh -u -l
# ERROR: Do not specify both upper and lower case conversion
together
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-D = Generate Documentation
-E = Execute Examples in Usagemsg
-v = Verbose mode - displays function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Example Usage:
my_template05_zbksh -v -u
my_template05_zbksh -v -l
"AutoContent" enabled
"Multi-Shell" enabled
Where:
Example Usage:
execl_zbksh "date; hostname"
typeset PROGRAM="execl_zbksh"
typeset VERSION="1.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset OPTIND="1"
typeset OPT_SSH="-o UserKnownHostsFile=/dev/null -o
StrictHostKeyChecking=no -o LogLevel=quiet -o BatchMode=yes -o
ConnectTimeout=30"
typeset CMD_SSH="ssh"
typeset SSHPORT=22
typeset SSHUSER="sshuser"
typeset SSHADDR=""
typeset RETCODE="99"
####################################################
####################################################
The command line arguments are verified, and
any problems cause the function to display the
usage message and return. One of the variable
conflict issues that may be encountered is a non-
NULL value for SSHADDR and a NULL value
for the SSHPORT. If the SSH address is
specified then the SSH Port must also be
specified. The same is true for the SSH User. If
the SSH address is specified, the SSH Port and
User must also have non-NULL values. These
values may be specified on the command line,
variable initialization section of the
“execl_zbksh” function, or in the configuration
file “execl_zbksh.conf”.
####################################################
####
#### Check the command line arguments to verify they are valid values
and that all
#### necessary information was specified.
####
####################################################
EXECMODE="${SSHADDR:+${CMD_SSH} ${OPT_SSH} -p
${SSHPORT} ${SSHUSER}@${SSHADDR}}"
${EXECMODE:-eval} "${@}"
RETCODE="${?}"
return ${RETCODE}
}
####
#### ####################################################
Where:
-v = Verbose mode - displays my_template01_k93 function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
CFILE=~/.my_template01_k93.conf
if [[ -f ${CFILE} ]]
then
(( VERBOSE == TRUE )) && cat ${CFILE}
. ${CFILE}
fi
return 0
}
####################################################
function my_template01_k93 {
typeset VERSION="1.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
MSG="${@}"
####################################################
####
#### Your shell function should perform it's specific work here.
#### All work performed by your shell function should be coded
#### within this section of the function. This does not mean that
#### your function should be called from here, it means the shell
#### code that performs the work of your function should be
#### incorporated into the body of this function. This should
#### become your function.
####
return 0
}
####################################################
my_template01_k93 "${@}"
Appendix B
Function: my_template02_zbksh
#!/usr/bin/ksh93
#!/bin/bash
#!/bin/zsh
####################################################
####
#### This script will run in KornShell93, Zshell, or Bash, all you need to do
#### is put the desired "shebang" line at the top of the script.
####
####################################################
function usagemsg_my_template02_zbksh {
CMD_ECHO="${GBL_ECHO:-echo -e }"
${CMD_ECHO} ""
${CMD_ECHO} "${1:+Program: ${1}}${2:+ Version: ${2}}"
${CMD_ECHO} "
Place a brief description ( < 255 chars ) of your shell
function here.
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-v = Verbose mode - displays my_template02_zbksh function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
\"AutoContent\" enabled
\"Multi-Shell\" enabled
"
}
####################################################
####
#### Description:
####
#### Place a full text description of your shell function here.
####
#### Assumptions:
####
#### Provide a list of assumptions your shell function makes,
#### with a description of each assumption.
####
#### Dependencies:
####
#### Provide a list of dependencies your shell function has,
#### with a description of each dependency.
####
#### Products:
####
#### Provide a list of output your shell function produces,
#### with a description of each product.
####
#### Configured Usage:
####
#### Describe how your shell function should be used.
####
#### Details:
####
#### Place nothing here, the details are your shell function.
####
####################################################
configure_my_template02_zbksh()
{
####
#### Notice this function is a POSIX function so that it can see local
#### and global variables from calling functions and scripts.
####
#### Configuration parameters can be stored in a file and
#### this script can be dynamically reconfigured by sending
#### the running script a HUP signal using the kill command.
####
#### Configuration variables can be defined in the configuration file using
#### the same syntax as defining a shell variable, e.g.: VARIABLE="value"
CMD_ECHO="${GBL_ECHO:-echo -e }"
if [[ -f ${MYT_CFILE} ]]
then
(( VERBOSE == TRUE )) && cat ${MYT_CFILE}
. ${MYT_CFILE}
fi
return 0
}
####################################################
function my_template02_zbksh {
typeset TRUE="${TRUE:-0}"
typeset FALSE="${FALSE:-1}"
typeset VERBOSE="${VERBOSE:-${FALSE}}"
typeset VERYVERB="${VERYVERB:-${FALSE}}"
typeset OPTIND="1"
typeset CMD_ECHO="${GBL_ECHO:-echo -e }"
typeset MYT_PROGRAM="my_template02_zbksh"
typeset MYT_VERSION="1.0"
typeset MYT_TGGLEUP="${FALSE}"
typeset MYT_TGGLELO="${FALSE}"
typeset MYT_ARGVALU=""
#### Call the configuration function and execute the configuration file.
configure_my_template02_zbksh "${MYT_PROGRAM}"
####################################################
####################################################
####################################################
####
#### Your shell function should perform its specific work here.
#### All work performed by your shell function should be coded
#### within this section of the function. This does not mean that
#### your function should be called from here, it means the shell
#### code that performs the work of your function should be
#### incorporated into the body of this function. This should
#### become your function.
####
if (( ${#@} > 0 ))
then
MYT_MSG="${@}"
fi
if [[ "_${MYT_MSG}" != "_" ]]
then
(( MYT_TGGLEUP == TRUE )) && typeset -u
MYT_MSG="${MYT_MSG}"
(( MYT_TGGLELO == TRUE )) && typeset -l
MYT_MSG="${MYT_MSG}"
#### If you need to define array values inside a while or until loop, and you
#### read input from a file, redirect input into the while loop instead of
#### using a pipe. Bash requires this syntax if you need the array values to
#### be visible outside of the loop.
####
#### Example Syntax:
#### grep X file > /tmp/tmp${$}.out
#### IDX="0"
#### while read VALUE
#### do ARRY[IDX++]="${VALUE}"
#### done < /tmp/tmp${$}.out
#### rm -f /tmp/tmp${$}.out
#### for i in "${ARRY[@]}"; do echo ${i}; done
####
return 0
}
####################################################
####################################################
####################################################
####
#### Main Body of Script Begins Here
####
####################################################
TRUE="0"
FALSE="1"
####
#### Extract the "shebang" line from the beginning of the script
####
#### Test the "shebang" line to determine what shell interpreter is specified
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
####
#### Modify the commands and script according to the shell interpreter
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" && emulate
ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on extended
globbing
####
#### Call the script function to begin processing
my_template02_zbksh "${@}"
Appendix C
Function: my_template03_zbksh
#!/usr/bin/ksh93
#!/bin/bash
#!/bin/zsh
####################################################
####
#### This script will run in KornShell93, Zshell, or Bash, all you need to do
#### is put the desired "shebang" line at the top of the script.
####
####################################################
function usagemsg_my_template03_zbksh {
stderr_zbksh ""
stderr_zbksh "${1:+Program: ${1}}${2:+ Version: ${2}}"
stderr_zbksh ""
stderr_zbksh "Place a brief description ( < 255 chars ) of your shell"
stderr_zbksh "function here."
stderr_zbksh ""
stderr_zbksh "Usage: ${1##*/} [-?vV] [-u] [-l]"
stderr_zbksh ""
stderr_zbksh " Where:"
stderr_zbksh " -u = Convert command line arguments to upper case"
stderr_zbksh " -l = Convert command line arguments to lower case"
stderr_zbksh " -v = Verbose mode - displays function info"
stderr_zbksh " -V = Very Verbose Mode - debug output displayed"
stderr_zbksh " -? = Help - display this message"
stderr_zbksh ""
stderr_zbksh "Author: Your Name ([email protected])"
stderr_zbksh ""
stderr_zbksh "\"AutoContent\" enabled"
stderr_zbksh "\"Multi-Shell\" enabled"
stderr_zbksh ""
}
####################################################
####
#### Description:
####
#### Place a full text description of your shell function here.
####
#### Assumptions:
####
#### Provide a list of assumptions your shell function makes,
#### with a description of each assumption.
####
#### Dependencies:
####
#### Provide a list of dependencies your shell function has,
#### with a description of each dependency.
####
#### Products:
####
#### Provide a list of output your shell function produces,
#### with a description of each product.
####
#### Configured Usage:
####
#### Describe how your shell function should be used.
####
#### Details:
####
#### Place nothing here, the details are your shell function.
####
####################################################
configure_my_template03_zbksh()
{
####
#### Notice this function is a POSIX function so that it can see local
#### and global variables from calling functions and scripts.
####
#### Configuration parameters can be stored in a file and
#### this script can be dynamically reconfigured by sending
#### the running script a HUP signal using the kill command.
####
#### Configuration variables can be defined in the configuration file using
#### the same syntax as defining a shell variable, e.g.: VARIABLE="value"
if [[ -f ${MYT_CFILE} ]]
then
(( VERBOSE == TRUE )) && cat ${MYT_CFILE}
. ${MYT_CFILE}
fi
return 0
}
####################################################
function my_template03_zbksh {
typeset TRUE="${TRUE:-0}"
typeset FALSE="${FALSE:-1}"
typeset VERBOSE="${VERBOSE:-${FALSE}}"
typeset VERYVERB="${VERYVERB:-${FALSE}}"
typeset OPTIND="1"
typeset MYT_PROGRAM="my_template03_zbksh"
typeset MYT_VERSION="1.0"
typeset MYT_TGGLEUP="${FALSE}"
typeset MYT_TGGLELO="${FALSE}"
typeset MYT_ARGVALU=""
#### Call the configuration function and execute the configuration file.
configure_my_template03_zbksh "${MYT_PROGRAM}"
#### Process the command line options and arguments.
####################################################
####################################################
####################################################
####
#### Your shell function should perform its specific work here.
#### All work performed by your shell function should be coded
#### within this section of the function. This does not mean that
#### your function should be called from here, it means the shell
#### code that performs the work of your function should be
#### incorporated into the body of this function. This should
#### become your function.
####
if (( ${#@} > 0 ))
then
MYT_MSG="${@}"
fi
if [[ "_${MYT_MSG}" != "_" ]]
then
(( MYT_TGGLEUP == TRUE )) && typeset -u
MYT_MSG="${MYT_MSG}"
(( MYT_TGGLELO == TRUE )) && typeset -l
MYT_MSG="${MYT_MSG}"
#### If you need to define array values inside a while or until loop, and you
#### read input from a file, redirect input into the while loop instead of
#### using a pipe. Bash requires this syntax if you need the array values to
#### be visible outside of the loop.
####
#### Example Syntax:
#### grep X file > /tmp/tmp${$}.out
#### IDX="0"
#### while read VALUE
#### do ARRY[IDX++]="${VALUE}"
#### done < /tmp/tmp${$}.out
#### rm -f /tmp/tmp${$}.out
#### for i in "${ARRY[@]}"; do echo ${i}; done
####
return 0
}
####################################################
####################################################
####################################################
####
#### Main Body of Script Begins Here
####
####################################################
####
#### Identify the function library directories to search
#### in the FPATH environment variable
FPATH=~/functions/adv_zbksh:~/functions:/usr/local/functions
export FPATH
####
#### Define the values for TRUE and FALSE,
#### In shell think, TRUE is zero (0) and FALSE is non-zero.
TRUE="0"
FALSE="1"
####
#### Extract the "shebang" line from the beginning of the script
####
#### Test the "shebang" line to determine what shell interpreter is specified
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
####
#### Modify the shell specific commands and script according to the shell
interpreter
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" && emulate
ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on extended
globbing
####
#### For those shell interpreters that do not directly support function libraries,
#### cache all the *_zbksh functions found in the FPATH directories.
####
if [[ "_${SHCODE}" == "_zshell" ]] ||
[[ "_${SHCODE}" == "_bash" ]]
then
#### Loop thru each directory in the FPATH list using a colon (:) delimeter.
#### Process each directory in reverse order to simulate results of
#### searching the FPATH directory.
IFS=":"
FDIRS=( ${FPATH} )
IFS=$' \t\n'
END=${#FDIRS[@]}
for (( IDX=END-1; IDX>=0; --IDX ))
do
FDIR="${FDIRS[${IDX}]}"
#### Gather a list of functions ending in *_zbksh from the directory and loop
#### thru each file using a “for†loop.
IFS=$' \t\n'
fi
####
#### Call the script function to begin processing
my_template03_zbksh "${@}"
Appendix D
Function Library
Function: echo_zbksh
function echo_zbksh {
####################################################
typeset PROGRAM="echo_zbksh"
typeset VERSION="1.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset OPTIND="1"
typeset FDNUM="1"
typeset RETCODE="99"
typeset CMD_ECHO="${GBL_ECHO:-echo -e }"
####################################################
####################################################
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
####
#### Check the command line arguments to verify they are valid values and
that all
#### necessary information was specified.
####
if [[ "_${FDNUM}" == "_" ]]
then
stderr_zbksh -- "# ERROR: File Descriptor number not specified"
return 2
fi
####
#### Display some program info and the command line arguments specified
#### if "VERBOSE" mode was specified.
####
####################################################
RETCODE="0"
if (( FDNUM == 1 ))
then
eval ${CMD_ECHO} "\"${@}\""
RETCODE="${?}"
fi
if (( FDNUM == 2 ))
then
eval ${CMD_ECHO} "\"${@}\"" >&2
RETCODE="${?}"
fi
return ${RETCODE}
}
####
#### ####################################################
Function: execl_zbksh
function execl_zbksh {
#### ####################################################
typeset PROGRAM="execl_zbksh"
typeset VERSION="1.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset OPTIND="1"
typeset OPT_SSH="-o UserKnownHostsFile=/dev/null -o
StrictHostKeyChecking=no -o LogLevel=quiet -o BatchMode=yes -o
ConnectTimeout=30"
typeset CMD_SSH="ssh"
typeset SSHPORT=22
typeset SSHUSER="sshuser"
typeset SSHADDR=""
typeset RETCODE="99"
####################################################
####################################################
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
####################################################
####
#### Check the command line arguments to verify they are valid values and
that all
#### necessary information was specified.
####
####################################################
#### Define the command execution mode, either local or remote depending
upon
#### the value of the SSHADDR variable. If it contains a remote IP address or
#### hostname, define the execution mode variable. Otherwise it are set to
#### NULL, which means the commands will run locally.
EXECMODE="${SSHADDR:+${CMD_SSH} ${OPT_SSH} -p
${SSHPORT} ${SSHUSER}@${SSHADDR}}"
${EXECMODE:-eval} "${@}"
RETCODE="${?}"
return ${RETCODE}
}
####
#### ####################################################
Function: find_dot_file_zbksh
find_dot_file_zbksh()
#### ####################################################
{
typeset DOT_PROGRAM="find_dot_file_zbksh"
typeset DOT_VERSION="1.0"
typeset DOT_TRUE="0"
typeset DOT_FALSE="1"
typeset DOT_VERBOSE="${DOT_VERBOSE:-${DOT_FALSE}}"
typeset DOT_VERYVERB="${DOT_VERYVERB:-${DOT_FALSE}}"
typeset OPTIND="1"
typeset DOT_FUNCNAME="find_dot_file_zbksh"
typeset DOT_ACTION="usagemsg"
typeset DOT_EXTFILE="./.find_dot_file_zbksh.usagemsg"
typeset DOT_RETCODE="99"
typeset DOT_DIR
typeset DOT_LINE
typeset DOT_RECURS="${DOT_RECURS:-${TRUE}}"
####################################################
if (( DOT_RECURS == DOT_TRUE ))
then
DOT_RECURS="${DOT_FALSE}"
find_dot_file_zbksh -f "find_dot_file_zbksh" -a "configure"
else
DOT_RECURS="${DOT_TRUE}"
return 0
fi
####################################################
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
####################################################
####
#### Check the command line arguments to verify they are valid values and
that all
#### necessary information was specified.
####
if [[ "_${DOT_ACTION}" != _[Cc][Oo][Nn][Ff][Ii][Gg][Uu][Rr][Ee] ]]
&&
[[ "_${DOT_ACTION}" != _[Uu][Ss][Aa][Gg][Ee][Mm][Ss][Gg] ]]
&&
[[ "_${DOT_ACTION}" == _[Dd][Oo][Cc][Uu][Mm][Ee][Nn][Tt] ]]
&&
[[ "_${DOT_ACTION}" == _[Ee][Xx][Aa][Mm][Pp][Ll][Ee] ]]
then
stderr_comment_zbksh -p "ERROR: Invalid Action Specified" -a
"${DOT_ACTION}"
find_dot_file_zbksh -f "find_dot_file_zbksh" -a "usagemsg"
return 11
fi
####################################################
####
#### Display some DOT_PROGRAM info and the command line arguments
specified
#### if "DOT_VERBOSE" mode was specified.
####
####################################################
####
####
####
DOT_RETCODE="0"
####################################################
#### Define the possible directory locations for the "dot" files in the FPATH
directories.
IDX="0"
IFS=$': \t\n'
for DIR in ${FPATH}
do
DOT_FPATHS[IDX++]="${DIR}"
done
IFS=$' \t\n'
####################################################
#### Define the possible directory locations for the "dot" files under the users
HOME.
IDX="0"
DOT_HOMES[IDX++]=~
DOT_HOMES[IDX++]=~/.adv_zbksh
DOT_HOMES[IDX++]=~/adv_zbksh
DOT_HOMES[IDX++]=~/functions/adv_zbksh
DOT_HOMES[IDX++]=~/functions
#### Define the possible directory locations for the "dot" files under
/usr/local.
IDX="0"
DOT_LOCALS[IDX++]="/usr/local/adv_zbksh"
DOT_LOCALS[IDX++]="/usr/local/functions/adv_zbksh"
DOT_LOCALS[IDX++]="/usr/local/functions"
DOT_LOCALS[IDX++]="/usr/local/scripts/adv_zbksh"
DOT_LOCALS[IDX++]="/usr/local/scripts"
#### Define the possible directory locations for the "dot" files under MAN
pages.
#### Define the "dot" file name extensions based on the CLI action specified.
#### Loop through each of the directory locations searching for the first
occurrence of
#### a matching "dot" file. The directories are search in order of HOMES,
LOCALS, MANS.
#### The first "dot" file found cause the loop to break.
DOT_EXTFILE="${DOT_DIR}/.${DOT_FUNCNAME}${DOT_EXTENSION}"
# verbose_comment_zbksh -v "${DOT_VERBOSE}" -p "External File
Found" -a "${DOT_EXTFILE}"
break
fi
done
#### If an external dot file exists, and the action is "configure", then
#### execute the file as a "dot" script in the current environment
#### If an external dot file exists, and the action is "document", then
#### display usagemsg, comments, and examples on STDOUT.
#### If an external dot file exists, and the action is "example", then
#### execute the function examples and display the results on STDOUT.
IFS=$' \t\n'
OPTIND="1"
return 0
}
####
#### ####################################################
Function: stderr_comment_zbksh
function stderr_comment_zbksh {
#### ####################################################
typeset PROGRAM="stderr_comment_zbksh"
typeset VERSION="1.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${TRUE}"
typeset VERYVERB="${FALSE}"
typeset PROMPT_STRING=""
typeset ANSWER_STRING=""
typeset COMMENT_FIRST=""
typeset COMMENT_LAST=""
typeset COMMENT_STRING=""
typeset DELETE_STRING=""
typeset PROMPT_WIDTH="40"
typeset OPTIND="1"
typeset RETCODE="99"
typeset SECZI="0"
typeset DOTCHAR="."
####################################################
typeset DOTS=""
typeset KPAT=""
for (( SECZI=0; SECZI<=${PROMPT_WIDTH}; ++SECZI ))
do
DOTS="${DOTS}${DOTCHAR}"
KPAT="${KPAT}?"
done
####################################################
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
'd') DOTCHAR="${OPTARG}"
DOTS=""
KPAT=""
for (( SECZI=0; SECZI<=${PROMPT_WIDTH}; ++SECZI ))
do
DOTS="${DOTS}${DOTCHAR}"
KPAT="${KPAT}?"
done;;
'w') PROMPT_WIDTH="${OPTARG}"
DOTS=""
KPAT=""
for (( SECZI=0; SECZI<=${PROMPT_WIDTH}; ++SECZI ))
do
DOTS="${DOTS}${DOTCHAR}"
KPAT="${KPAT}?"
done;;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
'D') find_dot_file_zbksh -f "${PROGRAM}" -a "document" && return
4;;
'E') find_dot_file_zbksh -f "${PROGRAM}" -a "example" && return
5;;
'?') find_dot_file_zbksh -f "${PROGRAM}" -a "usagemsg" && return 1
;;
':') find_dot_file_zbksh -f "${PROGRAM}" -a "usagemsg" && return 2
;;
'#') find_dot_file_zbksh -f "${PROGRAM}" -a "usagemsg" && return 3
;;
esac
done
####
#### Check the command line arguments to verify they are valid values and
that all
#### necessary information was specified.
####
####################################################
####################################################
####
#### Display the comments as provided on the CLI.
####
if [[ "_${COMMENT_FIRST}" != "_" ]]
then
COMMENT_STRING="# ${COMMENT_FIRST}"
stderr_zbksh "${COMMENT_STRING}"
fi
if [[ "_${PROMPT_STRING}" != "_" ]] &&
[[ "_${ANSWER_STRING}" != "_" ]]
then
PROMPT_STRING="${PROMPT_STRING}${DOTS}"
DELETE_STRING="${PROMPT_STRING#${KPAT}}"
PROMPT_STRING="${PROMPT_STRING%${DELETE_STRING}}"
COMMENT_STRING="# ${PROMPT_STRING}:
${ANSWER_STRING}"
stderr_zbksh "${COMMENT_STRING}"
fi
if [[ "_${COMMENT_LAST}" != "_" ]]
then
COMMENT_STRING="# ${COMMENT_LAST}"
stderr_zbksh "${COMMENT_STRING}"
fi
RETCODE="0"
return ${RETCODE}
}
####
#### ####################################################
Function: stderr_zbksh
function stderr_zbksh {
#### ####################################################
typeset PROGRAM="stderr_zbksh"
typeset VERSION="3.2"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset OPTIND="1"
typeset FDNUM="2"
typeset RETCODE="99"
####################################################
####################################################
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
####
#### Check the command line arguments to verify they are valid values and
that all
#### necessary information was specified.
####
####################################################
####
#### Display some program info and the command line arguments specified
#### if "VERBOSE" mode was specified.
####
####################################################
return ${RETCODE}
}
####
#### ####################################################
Function: stdout_zbksh
function stdout_zbksh {
#### ####################################################
typeset PROGRAM="stdout_zbksh"
typeset VERSION="1.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset OPTIND="1"
typeset FDNUM="1"
typeset RETCODE="99"
####################################################
####################################################
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
####
#### Check the command line arguments to verify they are valid values and
that all
#### necessary information was specified.
####
####################################################
####
#### Display some program info and the command line arguments specified
#### if "VERBOSE" mode was specified.
####
####################################################
return ${RETCODE}
}
####
#### ####################################################
Function: verbose_comment_zbksh
function verbose_comment_zbksh {
#### ####################################################
typeset PROGRAM="verbose_comment_zbksh"
typeset VERSION="1.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset TGGL_VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset PROMPT_STRING=""
typeset ANSWER_STRING=""
typeset COMMENT_FIRST=""
typeset COMMENT_LAST=""
typeset PROMPT_WIDTH="40"
typeset OPTIND="1"
typeset RETCODE="99"
####################################################
####################################################
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
####
#### Check the command line arguments to verify they are valid values and
that all
#### necessary information was specified.
####
####################################################
####################################################
####
#### Display some program info and the command line arguments specified
#### if "VERBOSE" mode was specified.
####
if (( TGGL_VERBOSE == TRUE ))
then
stderr_comment_zbksh ${COMMENT_FIRST:+-c
"${COMMENT_FIRST}"} ${PROMPT_STRING:+-p
"${PROMPT_STRING}"} ${ANSWER_STRING:+-a
"${ANSWER_STRING}"} ${COMMENT_LAST:+-C
"${COMMENT_LAST}"} -w ${PROMPT_WIDTH:-40}
fi
RETCODE="0"
return ${RETCODE}
}
####
#### ####################################################
Function: wikiAutoLoad_zbksh
function wikiAutoLoad_zbksh {
#### ####################################################
####
#### Description:
####
#### The purpose of this program is to provide the shell programmer or
system
#### administrator with an automated mechanism for uploading documentation
#### and content to a MediaWiki server. This shell script can be run from
#### any system in an organization to automatically upload information to a
#### centralized wiki documentation server.
####
#### Assumptions:
####
#### It is assumed the content to be uploaded is stored in files on the local
#### system. Each paged stored in a separate file. It is also assumed the
#### filename will be used as the Page title on the Wiki. When the file name
#### is processed by this script, characters such as underscores "_", commas
#### ",", periods ".", dashes "-" are replaced with spaces, and the file
#### extension can be removed via a command line option. So the user can
#### create files with names such as "My_Wiki_Page_to_Upload.html", and
this
#### script will upload this file to a wiki page named "My Wiki Page to
#### Upload".
####
#### Dependencies:
####
#### This script requires the "wget" command to send files and receive
#### cookies from the Wiki Server.
####
#### Unix Utilities:
#### sed
#### rm
####
#### GNU Utilities:
#### wget
####
#### Products:
####
#### This script uploads the contents of a file and creates or updates a
#### Mediwiki pages on a Wiki Server.
####
#### Configured Usage:
####
#### This script can be run from the command line or included in a library
#### and called as a function. One or more filenames containing content to
#### be uploaded to a Wiki Server must be specified on the command line or
an
#### error is generated.
####
#### Page titles for single file uploads can be specified using the "-t"
#### command line option. This option is only valid if a single file is
#### specified on the command line.
####
#### Bulk Uploads can be performed by specifying more than one filename on
#### the command line. The page title for each page in a bulk upload will be
#### the filename containing the content.
####
#### Deleting File Extentions from page titles during Bulk file uploads:
#### Multiple file extensions can be specified for the "-e" option by using
#### the pipe "|" delimiter between each file extension.
####
#### Multiple Categories can be specified on the command line as an
argument
#### to the "-C" option. To specify multiple categories, separate each
#### category specified with a comma ",".
####
#### Details:
####
####################################################
typeset PROGRAM="wikiAutoLoad_zbksh"
typeset VERSION="2.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset WAL_WIKIUSER="WikiSysop"
typeset WAL_WIKIPASS="abcd1234"
typeset WAL_APIURL="http://127.0.0.1/wiki/api.php"
typeset WAL_PAGETITLE=""
typeset WAL_CATEGORIES="Upload"
typeset WAL_FILEEXTEN="html"
typeset WAL_PRETAG="${FALSE}"
typeset WAL_CONVERT="${FALSE}"
typeset WAL_PREVIEW="${FALSE}"
typeset WAL_DD_COOKIES="/home/dfrench/tmp"
typeset WAL_DD_OUTFILE="/home/dfrench/tmp"
typeset WAL_WGETOUT="${WAL_DD_OUTFILE}/wget${$}.out"
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
if (( ${#@} == 0 ))
then
stderr_comment_zbksh -c "# ERROR: Upload File(s) not specified"
return 2
fi
####################################################
####
#### Display some program info and the command line arguments specified
#### if "VERBOSE" mode was specified.
####
####################################################
####################################################
####################################################
####################################################
####
#### Retrieve a login token from the wikimedia server
typeset WAL_LGNAME="lgname=${WAL_WIKIUSER}"
typeset WAL_LGPASS="lgpassword=${WAL_WIKIPASS}"
typeset WAL_ACTION="action=login"
typeset WAL_FORMAT="format=xml"
typeset WAL_OUTFILE="${WAL_DD_OUTFILE}/loginToken${$}.xml"
typeset
WAL_SAVECOOKIES="${WAL_DD_COOKIES}/loginTokenCookies${$}.txt"
WAL_GWLT_CMD="wget"
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"-O '${WAL_OUTFILE}'" )
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"--save-cookies '${WAL_SAVECOOKIES}'" )
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"--keep-session-cookies" )
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"--post-
data='${WAL_ACTION}&${WAL_FORMAT}&${WAL_LGNAME}&${WAL_LGPASS}
)
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"'${WAL_APIURL}'" )
stdout_zbksh -- "${WAL_GWLT_CMD}"
if [[ -r "${WAL_OUTFILE}" ]]
then
(( VERBOSE == TRUE )) && stderr_comment_zbksh -v "${VERBOSE}" -p
"wget output file" -a "${WAL_OUTFILE}" -d '>'
WAL_LGTOKEN=$( < "${WAL_OUTFILE}" )
WAL_LGTOKEN="${WAL_LGTOKEN#*token=\"}"
WAL_LGTOKEN="${WAL_LGTOKEN%\"*}"
else
(( VERBOSE == TRUE )) && stderr_comment_zbksh -v "${VERBOSE}" -p
"ERROR: wget output file" -a "${WAL_OUTFILE}" -d '>'
return 10
fi
####
#### Retrieve a login token from the wikimedia server
####################################################
####################################################
####################################################
####################################################
####################################################
####################################################
####
#### Create a login session on the wikimedia server
typeset WAL_ACTION="action=login"
typeset WAL_FORMAT="format=xml"
typeset WAL_OUTFILE="${WAL_DD_OUTFILE}/wikiLogin${$}.xml"
typeset
WAL_LOADCOOKIES="${WAL_DD_COOKIES}/loginTokenCookies${$}.txt"
typeset
WAL_SAVECOOKIES="${WAL_DD_COOKIES}/editTokenCookies${$}.txt"
stdout_zbksh "${WAL_WMLS_CMD}"
####
#### Create a login session on the wikimedia server
####################################################
####################################################
####################################################
#### Loop through each file specified on the command line and upload
#### it to the Mediawiki server, creating a new page or updating an
#### existing page.
#### If more than one upload file is specified on the command line,
#### use the file name (minus the extension) as the wikimedia page name.
#### extract the page contents from the file and store contents
#### in a shell variable
WAL_PAGETEXT=$( sed -e "s/'/\"/g;s/$/\\\r/g" < "${WAL_FILE}" )
#### Loop through each category specified on the command line and
#### add each category to the page contents.
IFS=$'.,:;|'
WAL_CATS=( ${WAL_CATEGORIES} )
IFS=$' \t\n'
typeset WAL_TITLES="titles=${WAL_PAGETITLE}"
typeset WAL_ACTION="action=query"
typeset WAL_FORMAT="format=xml"
typeset WAL_PROP="prop=info"
typeset WAL_INTOKEN="intoken=edit"
typeset WAL_OUTFILE="${WAL_DD_OUTFILE}/editToken${$}.xml"
typeset
WAL_LOADCOOKIES="${WAL_DD_COOKIES}/editTokenCookies${$}.txt"
typeset WAL_GWET_CMD="wget --debug --no-check-certificate"
stdout_zbksh "${WAL_GWET_CMD}"
####
#### Retrieve an "editToken" from the wikimedia server.
####################################################
####################################################
####################################################
####################################################
####################################################
####################################################
####
#### Upload the page contents to the wikimedia Server.
typeset WAL_TITLE="title=${WAL_PAGETITLE}"
# typeset WAL_TEXT=$( stdout_zbksh "<P>${WAL_PAGETEXT}</P>" |
sed -e 's|^$|</P><P>|g' | uniq )
typeset WAL_TEXT="${WAL_PAGETEXT}"
typeset WAL_TEXT="text=${WAL_TEXT}"
typeset WAL_EDITTOKEN="token=${WAL_EDITTOKEN}"
typeset WAL_ACTION="action=edit"
typeset WAL_RECREATE="recreate"
typeset WAL_OUTFILE="${WAL_DD_OUTFILE}/editPage${$}.xml"
typeset
WAL_LOADCOOKIES="${WAL_DD_COOKIES}/editTokenCookies${$}.txt"
####
#### Upload the page contents to the wikimedia Server.
####################################################
####################################################
####################################################
done
####
#### ####################################################
Appendix E
Function: my_template04_zbksh
#!/usr/bin/ksh93
#!/bin/bash
#!/bin/zsh
####################################################
####
#### Description:
####
#### Place a full text description of your shell function here.
####
#### Assumptions:
####
#### Provide a list of assumptions your shell function makes,
#### with a description of each assumption.
####
#### Dependencies:
####
#### Provide a list of dependencies your shell function has,
#### with a description of each dependency.
####
#### Products:
####
#### Provide a list of output your shell function produces,
#### with a description of each product.
####
#### Configured Usage:
####
#### Describe how your shell function should be used.
####
#### Details:
####
#### Place nothing here, the details are your shell function.
####
####################################################
function my_template04_zbksh {
typeset TRUE="${TRUE:-0}"
typeset FALSE="${FALSE:-1}"
typeset VERBOSE="${VERBOSE:-${FALSE}}"
typeset VERYVERB="${VERYVERB:-${FALSE}}"
typeset OPTIND="1"
typeset MYT_PROGRAM="my_template04_zbksh"
typeset MYT_VERSION="1.0"
typeset MYT_TGGLEUP="${FALSE}"
typeset MYT_TGGLELO="${FALSE}"
typeset MYT_ARGVALU=""
typeset MYT_OPTIND="${OPTIND:-1}"
####################################################
####################################################
OPTIND="1"
while getopts ":vVulDE" OPTION
do
case "${OPTION}" in
'u') MYT_TGGLEUP="${TRUE}";;
'l') MYT_TGGLELO="${TRUE}";;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
'D') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "document" &&
return 4;;
'E') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "example" &&
return 5;;
'?') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "usagemsg" &&
return 1 ;;
':') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "usagemsg" &&
return 2 ;;
'#') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "usagemsg" &&
return 3 ;;
esac
done
####################################################
####################################################
####################################################
####
#### Your shell function should perform its specific work here.
#### All work performed by your shell function should be coded
#### within this section of the function. This does not mean that
#### your function should be called from here, it means the shell
#### code that performs the work of your function should be
#### incorporated into the body of this function. This should
#### become your function.
####
if (( ${#@} > 0 ))
then
MYT_MSG="${@}"
fi
if [[ "_${MYT_MSG}" != "_" ]]
then
(( MYT_TGGLEUP == TRUE )) && typeset -u
MYT_MSG="${MYT_MSG}"
(( MYT_TGGLELO == TRUE )) && typeset -l
MYT_MSG="${MYT_MSG}"
return 0
}
####################################################
####################################################
####################################################
####
#### Main Body of Script Begins Here
####
####################################################
####
#### Identify the function library directories to search
#### in the FPATH environment variable
FPATH=~/functions/adv_zbksh:~/functions:/usr/local/functions
export FPATH
####
#### Define the values for TRUE and FALSE,
#### In shell think, TRUE is zero (0) and FALSE is non-zero.
TRUE="0"
FALSE="1"
####
#### Extract the "shebang" line from the beginning of the script
####
#### Test the "shebang" line to determine what shell interpreter is specified
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
####
#### Modify the shell specific commands and script according to the shell
interpreter
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" && emulate
ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on extended
globbing
####
#### For those shell interpreters that do not directly support function libraries,
#### cache all the *_zbksh functions found in the FPATH directories.
####
if [[ "_${SHCODE}" == "_zshell" ]] ||
[[ "_${SHCODE}" == "_bash" ]]
then
#### Loop thru each directory in the FPATH list using a colon (:) delimeter.
#### Process each directory in reverse order to simulate results of
#### searching the FPATH directory.
IFS=":"
FDIRS=( ${FPATH} )
IFS=$' \t\n'
END=${#FDIRS[@]}
for (( IDX=END-1; IDX>=0; --IDX ))
do
FDIR="${FDIRS[${IDX}]}"
#### Gather a list of functions ending in *_zbksh from the directory and loop
#### thru each file using a “for†loop.
IFS=$' \t\n'
fi
####
#### Call the script function to begin processing
my_template04_zbksh "${@}"
Appendix F
Usage Message: wikiAutoLoad_zbksh
Function: wikiAutoLoad_zbksh Version: 2.0
Function: wikiAutoLoad_zbksh
function wikiAutoLoad_zbksh {
#### ####################################################
####
#### Description:
####
#### The purpose of this program is to provide the shell programmer or
system
#### administrator with an automated mechanism for uploading documentation
#### and content to a MediaWiki server. This shell script can be run from
#### any system in an organization to automatically upload information to a
#### centralized wiki documentation server.
####
#### Assumptions:
####
#### It is assumed the content to be uploaded is stored in files on the local
#### system. Each paged stored in a separate file. It is also assumed the
#### filename will be used as the Page title on the Wiki. When the file name
#### is processed by this script, characters such as underscores "_", commas
#### ",", periods ".", dashes "-" are replaced with spaces, and the file
#### extension can be removed via a command line option. So the user can
#### create files with names such as "My_Wiki_Page_to_Upload.html", and
this
#### script will upload this file to a wiki page named "My Wiki Page to
#### Upload".
####
#### Dependencies:
####
#### This script requires the "wget" command to send files and receive
#### cookies from the Wiki Server.
####
#### Unix Utilities:
#### sed
#### rm
####
#### GNU Utilities:
#### wget
####
#### Products:
####
#### This script uploads the contents of a file and creates or updates a
#### Mediwiki pages on a Wiki Server.
####
#### Configured Usage:
####
#### This script can be run from the command line or included in a library
#### and called as a function. One or more filenames containing content to
#### be uploaded to a Wiki Server must be specified on the command line or
an
#### error is generated.
####
#### Page titles for single file uploads can be specified using the "-t"
#### command line option. This option is only valid if a single file is
#### specified on the command line.
####
#### Bulk Uploads can be performed by specifying more than one filename on
#### the command line. The page title for each page in a bulk upload will be
#### the filename containing the content.
####
#### Deleting File Extentions from page titles during Bulk file uploads:
#### Multiple file extensions can be specified for the "-e" option by using
#### the pipe "|" delimiter between each file extension.
####
#### Multiple Categories can be specified on the command line as an
argument
#### to the "-C" option. To specify multiple categories, separate each
#### category specified with a comma ",".
####
#### Details:
####
####################################################
typeset PROGRAM="wikiAutoLoad_zbksh"
typeset VERSION="2.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset WAL_WIKIUSER="WikiSysop"
typeset WAL_WIKIPASS="abcd1234"
typeset WAL_APIURL="http://127.0.0.1/wiki/api.php"
typeset WAL_PAGETITLE=""
typeset WAL_CATEGORIES="Upload"
typeset WAL_FILEEXTEN="html"
typeset WAL_PRETAG="${FALSE}"
typeset WAL_CONVERT="${FALSE}"
typeset WAL_PREVIEW="${FALSE}"
typeset WAL_DD_COOKIES="/home/dfrench/tmp"
typeset WAL_DD_OUTFILE="/home/dfrench/tmp"
typeset WAL_WGETOUT="${WAL_DD_OUTFILE}/wget${$}.out"
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
while getopts ":vVu:p:a:t:c:o:C:e:zfxDE" OPTION
do
case "${OPTION}" in
'u') WAL_WIKIUSER="${OPTARG}";;
'p') WAL_WIKIPASS="${OPTARG}";;
'a') WAL_APIURL="${OPTARG}";;
't') WAL_PAGETITLE="${OPTARG}";;
'c') WAL_DD_COOKIES="${OPTARG}";;
'o') WAL_DD_OUTFILE="${OPTARG}";;
'C') WAL_CATEGORIES="${OPTARG}";;
'e') WAL_FILEEXTEN="${OPTARG}";;
'z') WAL_PREVIEW="${TRUE}";;
'f') WAL_PRETAG="${TRUE}";;
'x') WAL_CONVERT="${TRUE}";;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
'D') find_dot_file_zbksh -f "${PROGRAM}" -a "document" && return
4;;
'E') find_dot_file_zbksh -f "${PROGRAM}" -a "example" && return
5;;
'?') find_dot_file_zbksh -f "${PROGRAM}" -a "usagemsg" && return 1
;;
':') find_dot_file_zbksh -f "${PROGRAM}" -a "usagemsg" && return 2
;;
'#') find_dot_file_zbksh -f "${PROGRAM}" -a "usagemsg" && return 3
;;
esac
done
if (( ${#@} == 0 ))
then
stderr_comment_zbksh -c "# ERROR: Upload File(s) not specified"
return 2
fi
####################################################
####
#### Display some program info and the command line arguments specified
#### if "VERBOSE" mode was specified.
####
####################################################
####################################################
####################################################
####################################################
####
#### Retrieve a login token from the wikimedia server
(( VERBOSE == TRUE )) && stderr_comment_zbksh -v "${VERBOSE}" -p
"Function" -a "getWikiLoginToken_zbksh" -d '>'
typeset WAL_LGNAME="lgname=${WAL_WIKIUSER}"
typeset WAL_LGPASS="lgpassword=${WAL_WIKIPASS}"
typeset WAL_ACTION="action=login"
typeset WAL_FORMAT="format=xml"
typeset WAL_OUTFILE="${WAL_DD_OUTFILE}/loginToken${$}.xml"
typeset
WAL_SAVECOOKIES="${WAL_DD_COOKIES}/loginTokenCookies${$}.txt"
WAL_GWLT_CMD="wget"
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"-O '${WAL_OUTFILE}'" )
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"--save-cookies '${WAL_SAVECOOKIES}'" )
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"--keep-session-cookies" )
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"--post-
data='${WAL_ACTION}&${WAL_FORMAT}&${WAL_LGNAME}&${WAL_LGPASS}
)
WAL_GWLT_CMD=$( append_string_zbksh -1 "${WAL_GWLT_CMD}" -2
"'${WAL_APIURL}'" )
stdout_zbksh -- "${WAL_GWLT_CMD}"
if [[ -r "${WAL_OUTFILE}" ]]
then
(( VERBOSE == TRUE )) && stderr_comment_zbksh -v "${VERBOSE}" -p
"wget output file" -a "${WAL_OUTFILE}" -d '>'
WAL_LGTOKEN=$( < "${WAL_OUTFILE}" )
WAL_LGTOKEN="${WAL_LGTOKEN#*token=\"}"
WAL_LGTOKEN="${WAL_LGTOKEN%\"*}"
else
(( VERBOSE == TRUE )) && stderr_comment_zbksh -v "${VERBOSE}" -p
"ERROR: wget output file" -a "${WAL_OUTFILE}" -d '>'
return 10
fi
####
#### Retrieve a login token from the wikimedia server
####################################################
####################################################
####################################################
####################################################
####################################################
####################################################
####
#### Create a login session on the wikimedia server
typeset WAL_LGNAME="lgname=${WAL_WIKIUSER}"
typeset WAL_LGPASS="lgpassword=${WAL_WIKIPASS}"
typeset WAL_LGTOKEN="lgtoken=${WAL_LGTOKEN}"
typeset WAL_ACTION="action=login"
typeset WAL_FORMAT="format=xml"
typeset WAL_OUTFILE="${WAL_DD_OUTFILE}/wikiLogin${$}.xml"
typeset
WAL_LOADCOOKIES="${WAL_DD_COOKIES}/loginTokenCookies${$}.txt"
typeset
WAL_SAVECOOKIES="${WAL_DD_COOKIES}/editTokenCookies${$}.txt"
stdout_zbksh "${WAL_WMLS_CMD}"
####
#### Create a login session on the wikimedia server
####################################################
####################################################
####################################################
#### Loop through each file specified on the command line and upload
#### it to the Mediawiki server, creating a new page or updating an
#### existing page.
#### If more than one upload file is specified on the command line,
#### use the file name (minus the extension) as the wikimedia page name.
#### extract the page contents from the file and store contents
#### in a shell variable
#### Loop through each category specified on the command line and
#### add each category to the page contents.
IFS=$'.,:;|'
WAL_CATS=( ${WAL_CATEGORIES} )
IFS=$' \t\n'
####################################################
####################################################
####################################################
####
#### Retrieve an "editToken" from the wikimedia server.
typeset WAL_TITLES="titles=${WAL_PAGETITLE}"
typeset WAL_ACTION="action=query"
typeset WAL_FORMAT="format=xml"
typeset WAL_PROP="prop=info"
typeset WAL_INTOKEN="intoken=edit"
typeset WAL_OUTFILE="${WAL_DD_OUTFILE}/editToken${$}.xml"
typeset
WAL_LOADCOOKIES="${WAL_DD_COOKIES}/editTokenCookies${$}.txt"
typeset WAL_GWET_CMD="wget --debug --no-check-certificate"
stdout_zbksh "${WAL_GWET_CMD}"
####
#### Retrieve an "editToken" from the wikimedia server.
####################################################
####################################################
####################################################
####################################################
####################################################
####################################################
####
#### Upload the page contents to the wikimedia Server.
typeset WAL_TITLE="title=${WAL_PAGETITLE}"
# typeset WAL_TEXT=$( stdout_zbksh "<P>${WAL_PAGETEXT}</P>" |
sed -e 's|^$|</P><P>|g' | uniq )
typeset WAL_TEXT="${WAL_PAGETEXT}"
typeset WAL_TEXT="text=${WAL_TEXT}"
typeset WAL_EDITTOKEN="token=${WAL_EDITTOKEN}"
typeset WAL_ACTION="action=edit"
typeset WAL_RECREATE="recreate"
typeset WAL_OUTFILE="${WAL_DD_OUTFILE}/editPage${$}.xml"
typeset
WAL_LOADCOOKIES="${WAL_DD_COOKIES}/editTokenCookies${$}.txt"
####
#### Upload the page contents to the wikimedia Server.
####################################################
####################################################
####################################################
done
return 0
}
####
#### ####################################################
Appendix G
Standalone Shell Script:
my_template05.sh
#!/usr/bin/ksh93
#!/bin/bash
#!/bin/zsh
####################################################
####
#### Identify the function library directories to search
#### in the FPATH environment variable
FPATH=~/functions/adv_zbksh:~/functions:/usr/local/functions
export FPATH
####
#### Define the values for TRUE and FALSE,
#### In shell think, TRUE is zero (0) and FALSE is non-zero.
TRUE="0"
FALSE="1"
####
#### Extract the "shebang" line from the beginning of the script
####
#### Test the "shebang" line to determine what shell interpreter is specified
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
####
#### Modify the shell specific commands and script according to the shell
interpreter
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" && emulate
ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on extended
globbing
####
#### For those shell interpreters that do not directly support function libraries,
#### cache all the *_zbksh functions found in the FPATH directories.
####
if [[ "_${SHCODE}" == "_zshell" ]] ||
[[ "_${SHCODE}" == "_bash" ]]
then
#### Loop thru each directory in the FPATH list using a colon (:) delimeter.
#### Process each directory in reverse order to simulate results of
#### searching the FPATH directory.
IFS=":"
FDIRS=( ${FPATH} )
IFS=$' \t\n'
END=${#FDIRS[@]}
for (( IDX=END-1; IDX>=0; --IDX ))
do
FDIR="${FDIRS[${IDX}]}"
#### Gather a list of functions ending in *_zbksh from the directory and loop
#### thru each file using a “for†loop.
IFS=$' \t\n'
fi
####
#### Call the script function to begin processing
my_template05_zbksh "${@}"
Function: my_template05_zbksh
function my_template05_zbksh {
####################################################
####
#### Description:
####
#### Place a full text description of your shell function here.
####
#### Assumptions:
####
#### Provide a list of assumptions your shell function makes,
#### with a description of each assumption.
####
#### Dependencies:
####
#### Provide a list of dependencies your shell function has,
#### with a description of each dependency.
####
#### Products:
####
#### Provide a list of output your shell function produces,
#### with a description of each product.
####
#### Configured Usage:
####
#### Describe how your shell function should be used.
####
#### Details:
####
#### Place nothing here, the details are your shell function.
####
####################################################
typeset TRUE="${TRUE:-0}"
typeset FALSE="${FALSE:-1}"
typeset VERBOSE="${VERBOSE:-${FALSE}}"
typeset VERYVERB="${VERYVERB:-${FALSE}}"
typeset OPTIND="1"
typeset MYT_PROGRAM="my_template05_zbksh"
typeset MYT_VERSION="1.0"
typeset MYT_TGGLEUP="${FALSE}"
typeset MYT_TGGLELO="${FALSE}"
typeset MYT_ARGVALU=""
typeset MYT_OPTIND="${OPTIND:-1}"
####################################################
####################################################
OPTIND="1"
while getopts ":vVulDE" OPTION
do
case "${OPTION}" in
'u') MYT_TGGLEUP="${TRUE}";;
'l') MYT_TGGLELO="${TRUE}";;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
'D') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "document" &&
return 4;;
'E') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "example" &&
return 5;;
'?') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "usagemsg" &&
return 1 ;;
':') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "usagemsg" &&
return 2 ;;
'#') find_dot_file_zbksh -f "${MYT_PROGRAM}" -a "usagemsg" &&
return 3 ;;
esac
done
####################################################
####################################################
####################################################
####
#### Your shell function should perform its specific work here.
#### All work performed by your shell function should be coded
#### within this section of the function. This does not mean that
#### your function should be called from here, it means the shell
#### code that performs the work of your function should be
#### incorporated into the body of this function. This should
#### become your function.
####
if (( ${#@} > 0 ))
then
MYT_MSG="${@}"
fi
if [[ "_${MYT_MSG}" != "_" ]]
then
(( MYT_TGGLEUP == TRUE )) && typeset -u
MYT_MSG="${MYT_MSG}"
(( MYT_TGGLELO == TRUE )) && typeset -l
MYT_MSG="${MYT_MSG}"
return 0
}
#### ####################################################
# MYT_PROGRAM="my_template05_zbksh"
# VERSION="1.0"
MYT_MSG="Hello World!"
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-D = Generate Documentation
-E = Execute Examples in Usagemsg
-v = Verbose mode - displays function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Example Usage:
my_template05_zbksh -v -u
my_template05_zbksh -v -l
"AutoContent" enabled
"Multi-Shell" enabled
Documentation File:
.my_template05_zbksh.document
Program: my_template05_zbksh Version: 1.0
Place a brief description ( < 255 chars ) of your shell
function here.
Where:
-u = Convert command line arguments to upper case
-l = Convert command line arguments to lower case
-D = Generate Documentation
-E = Execute Examples in Usagemsg
-v = Verbose mode - displays function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Example Usage:
my_template05_zbksh -v -u
my_template05_zbksh -v -l
"AutoContent" enabled
"Multi-Shell" enabled
Description:
Assumptions:
Dependencies:
Products:
Configured Usage:
Details:
####################################################
+ eval my_template05_zbksh -v -u
+ my_template05_zbksh -v -u
# Program Name..........: my_template05_zbksh
# Version...............: 1.0
# MYT_MSG Variable Value: HELLO WORLD!
HELLO WORLD!
+ [[ _korn == _korn ]]
+ eval my_template05_zbksh -v -l
+ my_template05_zbksh -v -l
# Program Name..........: my_template05_zbksh
# Version...............: 1.0
# MYT_MSG Variable Value: hello world!
hello world!
+ [[ _korn == _korn ]]
Examples File:
.my_template05_zbksh.example
+ eval my_template05_zbksh -v -u
+ my_template05_zbksh -v -u
# Program Name..........: my_template05_zbksh
# Version...............: 1.0
# MYT_MSG Variable Value: HELLO WORLD!
HELLO WORLD!
+ [[ _korn == _korn ]]
+ eval my_template05_zbksh -v -l
+ my_template05_zbksh -v -l
# Program Name..........: my_template05_zbksh
# Version...............: 1.0
# MYT_MSG Variable Value: hello world!
hello world!
+ [[ _korn == _korn ]]
####
#### Extract the "shebang" line from the beginning of the script
read SHEBANG < "${0}"
export SHEBANG
####
#### Identify the function library directories to search
#### in the FPATH environment variable
FPATH=~/functions/adv_zbksh:~/functions:/usr/local/functions
export FPATH
if [[ -f ./.adv_zbksh.prefix ]]
then . ./.adv_zbksh.prefix
elif [[ -f ~/.adv_zbksh.prefix ]]
then . ~/.adv_zbksh.prefix
fi
####
#### Call the script function to begin processing
my_template05_zbksh "${@}"
TRUE="0"
FALSE="1"
# ####
# #### Extract the "shebang" line from the beginning of the script
#
# read SHEBANG < "${0}"
# export SHEBANG
#
####
#### Test the "shebang" line to determine what shell interpreter is specified
SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh* ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh* ]] && SHCODE="zshell"
export SHCODE
####
#### Modify the shell specific commands and script according to the shell
interpreter
GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn" ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" && emulate
ksh93
[[ "_${SHCODE}" == "_bash" ]] && shopt -s extglob # Turn on extended
globbing
####
#### For those shell interpreters that do not directly support function libraries,
#### cache all the *_zbksh functions found in the FPATH directories.
####
if [[ "_${SHCODE}" == "_zshell" ]] ||
[[ "_${SHCODE}" == "_bash" ]]
then
#### Loop thru each directory in the FPATH list using a colon (:) delimeter.
#### Process each directory in reverse order to simulate results of
#### searching the FPATH directory.
IFS=":"
FDIRS=( ${FPATH} )
IFS=$' \t\n'
END=${#FDIRS[@]}
for (( IDX=END-1; IDX>=0; --IDX ))
do
FDIR="${FDIRS[${IDX}]}"
#### Gather a list of functions ending in *_zbksh from the directory and loop
#### thru each file using a “for†loop.
IFS=$' \t\n'
fi
Appendix H
Function: execl_zbksh
function execl_zbksh {
#### ####################################################
typeset PROGRAM="execl_zbksh"
typeset VERSION="1.0"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset OPTIND="1"
typeset OPT_SSH="-o UserKnownHostsFile=/dev/null -o
StrictHostKeyChecking=no -o LogLevel=quiet -o BatchMode=yes -o
ConnectTimeout=30"
typeset CMD_SSH="ssh"
typeset SSHPORT=22
typeset SSHUSER="sshuser"
typeset SSHADDR=""
typeset RETCODE="99"
####################################################
####################################################
####
#### Process the command line options and arguments, saving
#### the values as appropriate.
####
####################################################
####
#### Check the command line arguments to verify they are valid values and
that all
#### necessary information was specified.
####
####################################################
#### Define the command execution mode, either local or remote depending
upon
#### the value of the SSHADDR variable. If it contains a remote IP address or
#### hostname, define the execution mode variable. Otherwise it are set to
#### NULL, which means the commands will run locally.
EXECMODE="${SSHADDR:+${CMD_SSH} ${OPT_SSH} -p
${SSHPORT} ${SSHUSER}@${SSHADDR}}"
${EXECMODE:-eval} "${@}"
RETCODE="${?}"
return ${RETCODE}
}
####
#### ####################################################
Hidden Configuration File:
.execl_zbksh.conf
####################################################
####
#### This is the configuration file for the program "execl_zbksh". The
#### values show below are the default values for each configurable variable.
#### If you want to change a value, copy the configuration line, uncomment
#### it, and change the value.
####
####################################################
# PROGRAM="execl_zbksh"
# VERSION="1.0"
# OPT_SSH="-o UserKnownHostsFile=/dev/null -o
StrictHostKeyChecking=no -o LogLevel=quiet -o BatchMode=yes -o
ConnectTimeout=30"
# CMD_SSH="ssh"
# SSHPORT=22
# SSHUSER="sshuser"
Usage: execl_zbksh [-?vV] [-p port] [-u username] [-a ipaddress] "cmdstring"
Where:
Example Usage:
execl_zbksh "date; hostname"