STDENV shell scripting
You can use the STDENV DD statement to specify a z/OS shell script that defines the parameters, environment variables, and other elements needed to start the Java virtual machine (JVM) for an IMS dependent region. More options are available to you if you use a shell script rather than members of the PROCLIB data set.
When you use the STDENV DD statement, the IMS dependent region ignores PROCLIB members DFSJVMEV (specified in the ENVIRON= JCL startup parameter) and DFSJVMMS (specified in the JVMOPMAS= JCL startup parameter). To learn more about the STDENV DD statement, see DD statements for IMS procedures.
To specify a shell script, code the STDENV DD statement with any of the following options. Data sets and concatenated files are read in the order that you list them:
- A single fully qualified data set specified with the DSNAME/DSN parameter.
- A single fully qualified file name specified with the PATH parameter.
- A concatenation of fully qualified data sets specified with the DSNAME/DSN parameter.
- A concatenation of fully qualified file names specified with the PATH parameter.
- A concatenation of fully qualified file names and fully qualified data sets.
- An in-stream data set specified as input using the * parameter.
DSNAME
and PATH
, specify FILEDATA=TEXT and PATHOPTS=ORDONLY as part of the PATH parameter. An ABEND can occur if these values are not specified, preceded by the message IEC020I: UNIX FILE POSITIONING ERROR.Shell script parameters
The following example shell scripts use z/OS shell (/bin/sh
) syntax.
To export parameters as environment variables that the IMS dependent region can recognize, precede each parameter with the export
keyword. For example, use the export keyword to specify the LIBPATH=
, JLEOPT=
, and the SMFINTERVAL=
parameters:
...
LIBPATH=/lib:/usr/lib:"${JAVA_HOME}"/bin
...
export LIBPATH="$LIBPATH"
export JLEOPT=Y
export SMFINTERVAL=6000
Export the Java class path as an environment variable with the name CLASSPATH
. Note that CLASSPATH
length is limited to 150K characters when you use the STDENV DD statement:
export JAVA_HOME=/usr/lpp/java/java180/J8.0
export CLASSPATH="${JAVA_HOME}"/lib:...
Export other IBM JVM options as an environment variable with the name IBM_JAVA_OPTIONS
:
IJO="-Xms256m"
IJO="$IJO -Xmx1024m"
export IBM_JAVA_OPTIONS="$IJO"
When you use a shell script, you can specify the following additional parameters.
JZOS_OUTPUT_ENCODING=codepage
specifies the code page to use for stdout
and stderr
encoding:
export JZOS_OUTPUT_ENCODING=Cp1047
JZOS_ENABLE_OUTPUT_TRANSCODING=true | false
specifies whether to use the code page that is specified in JZOS_OUTPUT_ENCODING
for stdout
and stderr
encoding. The default value is true
. If the value is set to false, the specified code page is ignored and raw bytes are written to stdout
and stderr
:
export JZOS_ENABLE_OUTPUT_TRANSCODING=false
Good scripting practices
Use the following practices when creating, maintaining, and validating shell scripts:- Avoid using in-stream data sets, which can make script syntax validation difficult.
- After making script changes, validate the revised script syntax immediately to identify potential errors.
- Make incremental changes and validate often to identify and isolate potential errors.
- Keep and organize your shell scripts in data sets or UNIX System Services files.
- Avoid long running loops when possible.
WAIT-INIT-INPROG
. To stop the stalled operation, issue the command /STO REGION ABDUMP FORCE. Learn more at /STOP REGION command. A sample shell script
export JAVA_HOME=/usr/lpp/java/java180/J8.0
LP=/tmp
LP="$LP":$JAVA_HOME/bin/j9vm/
LP="$LP":$JAVA_HOME/bin/
LP="$LP":$JAVA_HOME/lib/
LP="$LP":$JAVA_HOME/lib/compressedrefs/
LP="$LP":$JAVA_HOME/lib/
LP="$LP":/usr/lpp/ims/ims15/imsjava/lib/
export LIBPATH="$LP":
CP=/tmp
CP="$CP":$JAVA_HOME/
CP="$CP":$JAVA_HOME/lib/
CP="$CP":$JAVA_HOME/lib/ext
CP="$CP":/tmp/udbtest-0.0.1.jar
CP="$CP":/usr/lpp/ims/ims15/imsjava/imsudb.jar
export CLASSPATH="$CP":
IJO="-Xms256m"
IJO="$IJO -Xmx512m"
IJO="$IJO -Djzos.logging=E"
IJO="$IJO -Djzos.merge.sysout=false"
# Sample parameters from DFSJVMEV
export IBM_JAVA_OPTIONS="$IJO "
export CANCEL_PGM=N
export JLEOPT=N
#export SMFINTERVAL=6000
STDENV script validation
IMS dependent region initialization can stall if a script contains syntax errors or produces long running loops. Syntax errors are often caused by a missing text character, such as a double quotation mark, single quotation mark, square bracket, or curly brace ("
, '
, [ ]
, { }
, …). To prevent stalls, validate shell script syntax as you make changes and before you specify the script in the dependent region.
To validate your scripts, first verify that your user ID is configured to access a UNIX System Services shell (/bin/sh or /bin/tcsh). To learn more about shell access, see z/OS: Accessing the shells — the choices.
Next, use one of the following options to obtain shell access. Using an SSH session or the OSHELL command at the TSO/E READY prompt can yield a better user experience than OMVS because they provide more space to enter commands.
- Establish an SSH session between your computer and the target system by using a command line terminal and the command: ssh userID@hostname
- At the TSO/E READY prompt or from the ISPF Command Shell panel (ISRTSO), use
OSHELL
plus the UNIX System Services command you want to run. - Use the
OMVS
command from the ISPF Command Shell panel (ISRTSO) or at the TSO/E READY prompt to get a 3270 terminal interface to the z/OS shell.
With a connection established, use the UNIX System Services commands cat, | (pipe), and sh to validate the contents of your STDENV shell scripts.
- Use the cat command to read the contents of files and fully qualified data set members.
- Use the | (pipe) command to pass the output of cat as input to the z/OS shell
(/bin/sh
) for processing. - When starting the shell, use the -x option to make the shell print commands and arguments as they run.
As an example, enter the following commands to pass the contents of YOURHLQ.STDENV.CONFIGS(STDENV00)
as input to the shell script, and to print commands and arguments as they run:
cat "//'YOURHLQ.STDENV.CONFIGS(STDENV00)'" | /bin/sh -x
Use the same technique to validate STDENV scripts. For example, in the following script fragment, the data set member STDENV00 contains a missing closing curly brace in the second LP=
statement. This error makes the script is invalid because "${JAVA_HOME"
is supposed to be "${JAVA_HOME}"
.
...
export JAVA_HOME=/usr/lpp/java/java180/J8.0
LP=/tmp
LP="$LP":"${JAVA_HOME"/bin/j9vm/
...
To validate the script, print the commands and their arguments as they run, pipe the contents of the STDENV00
member into the z/OS shell, and specify the -x option. This example uses an SSH session. The shell prompt is signified by the # character:
# cat "//'YOURHLQ.STDENV.CONFIGS(STDENV00)'" | /bin/sh -x
The command produces the following output:
...
+ export JAVA_HOME=/usr/lpp/java/java180/J8.0
+ LP=/tmp
FSUM7728 bad ${} modifier
To identify and isolate errors, compare the original script to the output. In this case, the line in the script that has the error is replaced with the message FSUM7728 bad ${} modifier. To validate the script, correct the error and rerun the script using the same cat, |, and -x technique. Repeat until the entire script runs successfully.
How to use the commands cat, | (pipe), and sh with data sets and UNIX System Services files
The following examples describe how to validate STDENV scripts that reside in single or multiple data sets, single or multiple Unix System Services files, or a combination of data sets and files. Each example shows how to perform the same action using the SSH, OSHELL, and OMVS shell access options. Unless specified otherwise, you run each command by pressing the Enter (or Return) key on your computer keyboard.
Example 1 - Single data set
In this example, the STDENV shell script is in a single fully qualified data set member:
YOURHLQ.STDENV.CONFIGS(STDENV00)
To validate the STDENV shell script, run one of the following commands.
Using an SSH session:
# cat "//'YOURHLQ.STDENV.CONFIGS(STDENV00)'" | /bin/sh -x
Using the OSHELL command at the TSO/E READY prompt:
READY OSHELL cat "//'YOURHLQ.STDENV.CONFIGS(STDENV00)'" | /bin/sh -x
Using an OMVS session:
===> cat "//'YOURHLQ.STDENV.CONFIGS(STDENV00)'" | /bin/sh -x
Example 2 - Multiple data sets
In this example, the STDENV shell script spans across multiple data set members:
"YOURHLQ.STDENV.CONFIGS(STDENV00)"
"YOURHLQ.STDENV.CONFIGS(STDENV01)"
To validate the STDENV shell script, run one of the following commands. Notice that the fully qualified data set members are separated by a blank.
Using an SSH session:
# cat "//'YOURHLQ.STDENV.CONFIGS(STDENV00)'"
"//'YOURHLQ.STDENV.CONFIGS(STDENV01)'" | /bin/sh -x
Using the OSHELL command at the TSO/E READY prompt:
READY OSHELL cat "//'YOURHLQ.STDENV.CONFIGS(STDENV00)'"
"//'YOURHLQ.STDENV.CONFIGS(STDENV01)'" | /bin/sh -x
Using an OMVS session (note that you cannot easily copy or paste, and that the size of the command on each line is limited):
===> cat "//'YOURHLQ.STDENV.CONFIGS(STDENV00)'"
"//'YOURHLQ.STDENV.CONFIGS(STDE
NV01)'" | /bin/sh -x
If the command is too long to fit in the OMVS session command prompt, you can use the command continuation character \ (backslash) to continue the command on the next line. After each use of the \ character, press Enter.
===> cat "//'YOURHLQ.STDENV.CONFIGS(STDENV00)'" \
===> "//'YOURHLQ.STDENV.CONFIGS(STDENV01)'" \
===> | /bin/sh -x
Example 3 - Single file in UNIX System Services
In this example, the STDENV shell script is in a single file in UNIX System Services.
" /yourPath/STDENV-configs/STDENV00.cfg"
To validate the STDENV shell script, run one of the following commands.
Using an SSH session:
# cat /yourPath/STDENV-configs/STDENV00.cfg | /bin/sh -x
Using the OSHELL command at the TSO/E READY prompt:
READY OSHELL cat /yourPath/STDENV-configs/STDENV00.cfg | /bin/sh -x
Using an OMVS session:
===> cat /yourPath/STDENV-configs/STDENV00.cfg | /bin/sh -x
Example 4 - Multiple files in UNIX System Services
In this example, the STDENV shell script resides in multiple files in UNIX System Services.
" /yourPath/STDENV-configs/STDENV00.cfg"
" /yourPath/STDENV-configs/STDENV01.cfg"
To validate the STDENV shell script, run one of the following commands. Notice that the file paths are separated by a blank.
Using an SSH session:
# cat /yourPath/STDENV-configs/STDENV00.cfg /yourPath/STDENV-configs/STDENV01.cfg | /bin/sh -x
Using the OSHELL command at the TSO/E READY prompt:
READY OSHELL cat /yourPath/STDENV-configs/STDENV00.cfg
/yourPath/STDENV-configs/STDENV01.cfg | /bin/sh -x
Using an OMVS session:
===> cat /yourPath/STDENV-configs/STDENV00.cfg
/yourPath/STDENV-configs/STDENV01.cfg | /bin/sh -x
If the command is too long to fit in the OMVS session command prompt, you can use the command continuation character \ (backslash) to continue the command on the next line. After each use of the \ character, press Enter.
===> cat /yourPath/STDENV-configs/STDENV00.cfg \
===> /yourPath/STDENV-configs/STDENV01.cfg \
===> | /bin/sh -x
Example 5 - Data set and UNIX System Services file
In this example, the STDENV shell script resides in a file in UNIX System Services and in a data set member.
" /yourPath/STDENV-configs/STDENV00.cfg"
"YOURHLQ.STDENV.CONFIGS(STDENV01)"
To validate the STDENV shell script, run one of the following commands. Notice that the file paths are separated by a blank.
Using an SSH session:
# cat /yourPath/STDENV-configs/STDENV00.cfg
"//'YOURHLQ.STDENV.CONFIGS(STDENV01)'" | /bin/sh -x
Using the OSHELL command at the TSO/E READY prompt:
READY OSHELL cat /yourPath/STDENV-configs/STDENV00.cfg
"//'YOURHLQ.STDENV.CONFIGS(STDENV01)'" | /bin/sh -x
Using an OMVS session:
===> cat /yourPath/STDENV-configs/STDENV00.cfg
"//'YOURHLQ.STDENV.CONFIGS(STDENV01)'" | /bin/sh -x
If the command is too long to fit in the OMVS session command prompt, you can use the command continuation character \ (backslash) to continue the command on the next line. After each use of the \ character, press Enter.
===> cat /yourPath/STDENV-configs/STDENV00.cfg \
===> "//'YOURHLQ.STDENV.CONFIGS(STDENV01)'" \
===> | /bin/sh -x
Error message examples
The following examples show common syntax errors and their related expected error messages. Note that your shell might display error messages with colons (::
) instead of square brackets ([]
) or curly braces ({}
):
FSUM7728 bad $:: modifier
Example 1 - A missing double quotation mark
STDENV00 is missing a double quotation mark "
:
export IBM_JAVA_OPTIONS="$IJO
or
export IBM_JAVA_OPTIONS=$IJO"
The resulting error message is as follows. Notice that the error message reports a missing closing quotation mark regardless of where the element is missing in the character string:
FSUM7729 missing closing """
Example 2 - A missing single quotation mark
STDENV00 is missing a single quotation mark '
:
APP_HOME='/tmp/
or
APP_HOME=/tmp/'
As with the missing double quotation mark, the resulting message identifies the error as a missing closing single quotation mark regardless of where the single quotation mark should appear in proper syntax:
FSUM7729 missing closing "'"
Example 3 - A missing opening or closing square bracket
STDENV00 contains a missing open square bracket [
:
if [ -t "$fd" || -p /dev/stdin ] ]
Though the error is caused by a missing open bracket, notice that the resulting error message reports a different syntax problem:
FSUM7332 syntax error: got ]], expecting then
STDENV00 contains a missing close square bracket ]
:
if [[ -t "$fd" || -p /dev/stdin ]
The resulting error message is as follows. Notice that the reported error is different from the actual cause:
FSUM7332 syntax error: got EOF, expecting ]]
Example 4 - A missing opening or closing curly brace
STDENV00 is missing a closing curly brace }
:
APP_HOME="${JAVA_HOME"
The resulting error message is as follows:
FSUM7728 bad ${} modifier