# dmk.sh / dmk-core.pl

Script that generates a bash / ksh (Unix) or cmd / Ps1 (Windows) environment file to be sourced by dmk.sh, dmk.cmd, dmk.Ps1

## Overview of setting the environment for Oracle

To set the shell-environment for Oracle, DMK will generate a temporary script that will be sourced afterwards. The `dmk-core.pl` script is called by a platform specific `dmk.sh` (Unix) or `dmk.cmd` (optionally dmk.ps1) (Windows) wrapper script and will generate a platform specific environment file. This environment file is sourced by the calling wrapper-script. The environment file is stored under Unix as `/tmp/dmk_{date}_{process-id_}.ksh`, and `%TEMP%\dmk_{timestamp}.cmd` (or Ps1) under Windows. It will be deleted after sourcing, except variable `DEBUG` is set.

There are variables that are always set by dmk (usually prefixed by `DMK_`, but also Oracle-mandatory variables like `ORACLE_HOME`).

* They are derived by DMK at runtime (e.g. version of oracle: `DMK_ORA_VER`)
* or or from a configuration file (e.g. `DMK_SID_TYPE` from ora\_sids). All these variables can be seen as a `[INTERNAL]` section.

Other variables can be set by configuration files that are organized in sections. The configuration files have different priorities (least to highest).

* `$etc/dmk.conf.default`
* `$etc/dmk.conf.global`
* `$etc/dmk.conf.local`
* `$cda/dmk/$ORACLE_SID.conf`
* `$cda/dmk/pdbs/$DMK_SID_PDB_NAME`

Within the **same** section (e.g. \[GLOBAL], see below), the value of a later configuration file **replaces** the value of an earlier configuration file with one exception: If the value is `<keep>`, then the value is kept from the former configuration files. This can be used to keep the default value, and to only change the option to nowarn.

Example: If a variable for the same section is defined in `dmk.conf.default` and `dmk.conf.local`, then the value of `dmk.conf.local` is kept for this section.

The environment file will be generated in the following order of the sections of the configuraton files:

* `[INTERNAL]`
* `[GLOBAL]`
* `[SID]`
* `[$ORACLE_SID]`
* `[$ORACLE_SID.$DMK_SID_PDB_NAME]`

### Store or reset the initial environment

All shell path variables that DMK will adapt

* PATH
* SQLPATH
* LD\_LIBRARY\_PATH (Unix only)

will initially be saved in `SAVE_DMK_INT_${var}` variables.

The same applies to path-variables that are modified by the '+' or '-' operator of a configuration entry, or variables containing variables (e.g. X=$a/b). These variables are saved as `SAVE_DMK_CFG_${var}` variables.

Also all variables set by the `[$ORACLE_SID]` or PDB section of a configuration file are stored in `SAVE_DMK_CFG_${var}` variables.

The next time of calling this script, it will first restore the value of `SAVE_DMK_*_{{var}}` to `${var}`;

## Workflow of dmk-core.pl

### Initialize the environment

Set or reset the variables and aliases (`[INTERNAL]` section) that are always set by DMK ilike ORACLE\_HOME, DMK\_DIAG\_DEST or the alias cdd.bin;

Afterwards, read the configuration files in the defined order as described above.

### Setting the Perl to use (PERL\_EXEC)

To initially start DMK, a Perl binary is required, chosen with the following priority (in dmk.sh / dmk.cmd)

* The Perl specified in $PERL\_EXEC variable
* The Perl found in $PATH
* The Perl in the 1st ORACLE\_HOME

After startup, DMK sets the variables `DMK_INITIAL_PERLBIN` and `DMK_INITIAL_PERLLIB` (These variables are NOT evaluated for initial startup. It will be set to the Perl that effectively was used at inital startup).

For Windows: The first time DMK is started, a desktop link is created and PERL\_EXEC is hardcoded to the Perl found with above priority (to avoid re-evaluation every time).

After setting the environment of a SID, per default the Perl of the current environment `$ORACLE_HOME/perl/bin/perl` is used (environment-Perl). The advantage is that the Perl `DBD::Oracle` module is available for the current software release. The Perl to use for this environment is stored in the variable `PERL_EXEC`; And the directory of it is added to the beginning of the `PATH` variable, so `perl` usually calls the environment-Perl.

If there is no working `$ORACLE_HOME/perl/bin/perl` found, then DMK will fallback to the initial Perl.

Alternatively you can explicitly configure a Perl to use:

```
var::PERL_EXEC::=::nowarn::/usr/local/bin/perl::
```

### Setting the PATH variable

The `$PATH` variable will be built with Perl/Oracle specific path components in front of the $PATH (from initial environment plus modifications by configuration lines), followed by the `bin/` directories of the tools in `$DMK_HOME`.

* `PATH=$DMK_PRE_PATH:$PATH:$DMK_POST_PATH`

If for any reason you have to modify the internally generated path components, then you have to modify `DMK_PRE_PATH` or `DMK_POST_PATH` via configuration files. `$PATH` is the path set by the OS if you did not modify it.

### Setting SQLPATH from directories

All directories ${DMK\_BASE}/\*/sql will be added in front of the initial SQLPATH; If there are subdirectories sql/oracleXX or sql/oracleXXYY (e.g. sql/oracle19 or sql/oracle1120) and the number XX or XXYY is equal or lower than the current Oracle version it will be added in descending order before all other directories. Example for Oracle 19.7.0:

* `$DMK_BASE/dmk_sql/sql/oracle1970`
* `$DMK_BASE/dmk_sql/sql/oracle1960`
* `$DMK_BASE/dmk_sql/sql/oracle19`
* `$DMK_BASE/dmk_sql/sql/oracle1800`
* `$DMK_BASE/dmk_sql/sql/oracle1220`

With the + or - operator you can append individual path components in front or at the end.

### Setting LD\_LIBRARY\_PATH for new ORACLE\_HOME

Add `$ORACLE_HOME/lib` in front of the initial `$LD_LIBRARY_PATH` variable

### Setting variables related to the new ORACLE environment

the values are taken from the configuration files `$etc/ora_homes` and `$etc/ora_sids`, or determined at runtime

* `DMK_DBS` (runtime)
* `DMK_ORACLE_HOME_RW` (runtime)
* `DMK_HOME_PRODUCT` (ora\_homes)
* `DMK_HOME_INVNAME` (ora\_homes)
* `DMK_HOME_DUMMYNAME` (ora\_homes)
* `DMK_ORA_ADMIN_SID` (runtime)
* `DMK_ROOH` (runtime)
* `DMK_SID_TYPE` (ora\_sids)
* `DMK_SID_CRSTYPE` (ora\_sids)
* `DMK_SID_INSTANCES` (ora\_sids)

### Setting alertlog and diagnostic dest variables

For databases < 11g the the alertlog is in `$ORACLE_BASE/admin/[sid]/bdump/`

For Databases 11g and later the alertlog is usually in the `$ORACLE_BASE/diag/[type]/[db_unique_name]/[Sid]/trace/`; If not, the variable `$DMK_ORA_SID_ALERTLOG` with the full path has to be configured.

### Setting PDB variables and aliases for the current SID

The variable `DMK_ORA12C_PDBS` contains the PDBs of the current SID (without PDB$SEED). The `DMK_SID_PDB_NAME` is set to the current PDB (or CDB$ROOT)

Additionally to the `{SID}.{PDB}` aliases there will also be `{PDB}` aliases for every PDB of the current SID (if there is no SID with the same name).

### Modifying \*PATH variables by + or - operator

For Path variables (e.g. $PATH, $SQLPATH, $LD\_LIBRARY\_PATH) you can use the '+' operator to append directories in front (option 'begin') or at the end (option 'end') of the variable. Or you can use the '-' operator to remove directories in front (option 'begin'), at the end (option 'end') or everywhere (option 'all') from the variable. If you have configured both '+' and '-', then the '-' will be first applied (per section).

### Setting the bash prompt

If the current shell is bash and PS1BASH is defined, then PS1 will be replaced by this bash-specific prompt.

### Setting the Windows prompt

The prompt must be set after setting all variables, otherwise it may contain variable-values of the former environment. In cmd.exe the prompt is set with the 'PROMPT' variable. In powershell.exe, the prompt is set by the function 'prompt'. See the dmk.conf.default for an example.

### Writing the environment file

Now, the environment file is written to the `/tmp` (Unix) / `%TEMP%` (Win) directory, and afterwards sourced by the calling dmk.\*sh / dmk.(cmd|Ps1) script.

This file is removed afterwards, except you do a `export DEBUG=1` before sourcing dmk.sh

### Creating a desktop link for Windows

If there is no `DMK.*.lnk` on the Windows Desktop to startup a DMK session and the variable `DMK_NO_DESKTOP_LINK` is not set, DMK will copy such a desktop link from `dmk/templates/etc` and adapt it with `cscript.exe` of windows scripting host for your current environment. Example:

`%windir%\system32\cmd.exe /K set PERL_EXEC=C:\Perl\bin\perl.exe & T:\dmk\bin\dmk.cmd && C:\Perl\bin\perl.exe T:\dmk\bin\status.pl process`

If the link already exists, it will not be updated. If you rename the link, it will be re-created with the original name, except you set `DMK_NO_DESKTOP_LINK`.

After the link is created by DMK, you can adapt the terminal properties like inital size, color and font.

### Dependencies

dmk-core uses many functions of DMK\_ENV.pm, to have more information about it, call `perldoc $DMK_HOME/lib/DMK_ENV.pm`
