#### PREPROCESS

#### Synopsis

    HELP:   Execute command before a file is opened
    TYPE:   OBJECT
    SYNTAX: PREPROCESS[(NET.{},COMMAND='str',TIMEOUT=num,ACCEPT[num...],STDOUT='str'/LOG/STREAM/STDERR,STDERR='str'/LOG/STREAM/STDOUT,CCSID='str'/DEFAULT/ASCII/EBCDIC/SYSTEM/LOCAL,CHRMODE=STOP/IGNORE/SUBSTITUTE/IDENTITY/TRANSLIT)...]

#### Description

The global pre command object can be used to execute commands before processing of any files starts. With the NET overlay, commands can be executed on remote systems. If no connection information is provided, the command is executed locally.

If a command is specified, it is executed on the target (local or remote) in an operating system dependent manner. An optional timeout can be specified, which limits the maximum execution time. Timeouts are not supported on all platforms. The following paragraphs describe the differences between the supported execution environments:

POSIX (Linux/Solaris/AIX/USS): The command is executed by the default system shell as if run via `/bin/sh -c "command"`. If a non-zero timeout is specified and the execution time exceeds the timeout value, the process and all its children are killed and a timeout error occurs. Windows: The command is executed by the Windows command line interpreter as if run via `cmd.exe /C command`. If a non-zero timeout is specified and the execution time exceeds the timeout value, the process and all its children are killed and a timeout error occurs. z/OS: The command is executed through the `system()` function which allows you to call commands, EXECs, CLISTs or executable modules under MVS and TSO/E. For more information on how to build the command string, please refer to the documentation of the `system()` function (ANSI variant) in IBM's "z/OS XL C/C++ Runtime Library Reference". Timeouts are not supported. Therefore, specifying a timeout value has no effect. The command's termination is always waited for before processing by FLAM continues. SSH: The command is executed on the remote host through the command execution feature in SSH as described in RFC4254. To be able to execute commands on a remote SSH host, the server must support this feature and the login user must have sufficient privileges to run commands. How the command is executed is server-specific. OpenSSH on a Linux host usually runs the command via `/bin/sh -c "command"` and sends the standard output and standard error streams through the SSH channel back to the client. If a non-zero timeout is specified and the execution time exceeds the timeout value, a timeout error occurs. No attempt is made to terminate the process on the remote host because this not supported by the SSH protocol and is highly specific to the (unknown) operating system on the remote host. Therefore, the remote process may or may terminate successfully after the timeout was reached.

The exit code is logged if the command terminates normally. It is possible to provide a list of acceptable exit codes. When the command terminates with an acceptable exit codes, it is considered successful and file processing continues. All other exit codes are considered a failure. The only default acceptable exit code is 0.

The action taken when a command fails depends on whether it is a pre or post command. If a pre command fails, an error is logged and the conversion of the file (for per-file pre commands) or the whole conversion (for global pre commands) is not performed. If a post command fails, an error is logged and processing of the next file (for per-file post commands) continues. For failed commands, the beginning of the standard error stream is printed as part of the error trace if the STDERR parameter has not been assigned to help you debug the issue.

The standard output and standard error streams of the executed command are ignored by default. By specifying a file URL for the STDOUT or STDERR parameter, the respective output stream can be written to the log (STDOUT=:LOG), to the respective output streams of the current process (STDOUT=:STDOUT / STDERR=:STDERR) or to a file at the given path (can be remote). By setting STDOUT=:STDERR or STDERR=:STDOUT, the respective streams output can also be redirected to the location of the respective other stream's output. For example, by setting STDOUT=/any/path and STDERR=:STDOUT both output streams can be redirected to the same file without having to specify the path twice. Please note that by multiplexing both output streams into one file, the order of lines might not accurately reflect the order in which they were written by the executed application if it alternates between writing to stdout and stderr.

If command output is written to the log, character conversion to the local character set is performed automatically (relevant for remote execution). The CCSID parameter can be used to set the character set that the output from the remote system is encoded in. If not specified, FLAM uses UTF-8 as default and falls back to Latin-1 for remote command execution and the local character set for local command execution. This works well if the output is text. Please note that lines longer than 1023 bytes are truncated. As a result, a warning is written to the log (this will result in completion code 1). Non-convertible characters are transliterated. If this is not possible, they are ignored (like CHRMODE=TRANSLIT).

When writing the output to a file (local or remote) by specifying a file URL, character conversion can be activated by setting the parameter CCSID and/or by appending the target CCSID to the URL (e.g. ssh://user@host/myfile/&UTF-8). Otherwise, the binary output is written as-is. Using the CCSID parameter activates text mode processing. If the target CCSID is defined via the URL, a binary transfer of the character converted data stream is performed. An error occurs if character conversion or the write operation fails. The CHRMODE parameter can be used to change the handling of non-convertible or damaged characters. This parameter also enforces character conversion. By default, character conversion between identical CCSIDs are skipped.

#### Arguments

- `STRING: COMMAND='str' - Command(s) to be executed`
- `NUMBER: TIMEOUT=num - Timeout for the command in seconds (not for local z/OS commands) [0=infinite]`
- `NUMBER: ACCEPT[num...] - List of exit codes that are considered as successful execution [0]`
- `STRING: STDOUT='str'/LOG/STREAM/STDERR - Where to write standard output of the command [IGNORE]`
  - `LOG - Write standard output to the log`
  - `STREAM - Write standard output to local stdout stream`
  - `STDERR - Write standard output defined by STDERR parameter`
- `STRING: STDERR='str'/LOG/STREAM/STDOUT - Where to write standard error of the command [IGNORE]`
  - `LOG - Write standard error output to the log`
  - `STREAM - Write standard error output to local stderr stream`
  - `STDOUT - Write standard error output defined by STDOUT parameter`