The Korn shell, or POSIX shell, allows you to run one or more
commands as background processes. These commands, run from within a shell script, are
called coprocesses.
Designate a coprocess by placing the |& operator after a command. Both standard input and output of
the command are piped to your script.
A coprocess must meet the following restrictions:
- Include a newline character at the end of each
message
- Send each output message to standard output
- Clear its standard output after each message
Coprocesses, sometimes called coroutines, consist of two or more
processes programmed to run simultaneously, and typically communicate with each
other. The parent program (script) will start a command or program in the
background that is able to have two-way communication with it. In more technical
terms, the standard input and output of the background program is connected to the parent
program with a pipe.
Coprocesses are useful if you want to provide an interface to
existing/legacy programs for example SQL*Plus
If you start a background process by appending |& to a command instead of &, the Korn shell will set up a
special two-way pipeline between the parent shell and the
new background process. The command read -p in the
parent shell reads a line of the background process standard output; similarly, print
-p in the parent shell feeds the standard input of the background process.
Notice, that the parent shell communicates with the background
process independently of its own standard input and output. The background process need
not have any idea that a shell script is communicating with it in this manner. This means
that the background process can be any pre-existing program that uses its standard input
and output in normal ways, for example SQL*Plus.
Here is an Example which checks the Oracle database for invalid
objects using SQL*Plus and a parent shell script. If any invalid objects are found a
message is mailed to an administrator.
#!/bin/ksh
# -------------------------------------------------------------
#
# Purpose: Check for INVALID objects
#
# -------------------------------------------------------------
#
# DEBUG
# set -x
ORACLE_HOME=/opt/oracle/product/10.2.0
export ORACLE_HOME
SENDTO="xxx.yyy@zzz.com"
export SENDTO
USR_PWD="usr/pwd";
export USR_PWD
SID_LIST="TEST"
for i in ${SID_LIST}
do
ORACLE_SID=${i}
export ORACLE_SID
# Open pipe to Oracle sqlplus
${ORACLE_HOME}/bin/sqlplus -s ${USR_PWD} |&
# Initialize Buffer
OUT=""
# Check for INVALID objects
print -p "SET heading OFF;"
print -p "SELECT count(*)
FROM dba_objects
WHERE status != 'VALID'
AND owner NOT IN ('PUBLIC');"
read -p OUT
# Remove empty lines from output
((i=0))
while [ "${OUT}" = "" -a "${i}" -lt "5" ]; do
read -p OUT 2>/dev/null
((i=i+1))
done
# Found any INVALID objects? (OUT > 0)
if [ "${OUT}" != "0" ]
then
mail -s "`uname -n`: ${OUT} invalid objects
found in ${ORACLE_SID}"
$SENDTO
fi
# Close sqlplus and Close
# co-processes' file
descriptors
print -p "exit 0" 2>/dev/null
exec 3>&p
done