Le script oraenv expliqué - The oraenv script explained
Introduction
Sous Unix/Linux, deux scripts shell permettent de mettre à jour les variables d'environnement Oracle pour se connecter à une base; Windows ne sera pas abordé ici. Il s'agit des fichiers oraenv et coraenv, dans /usr/local/bin et $ORACLE_HOME/bin. coraenv s'utilise avec le C Shell et oraenv avec les shells Bourne, Bash et Korn. Ils mettent à jour, via la commande export, les variables ORACLE_SID, ORACLE_HOME, ORACLE_BASE, PATH et LD_LIBRARY_PATH.
Au minimum, il faut que les variables ORACLE_SID, ORACLE_HOME et ORACLE_BASE soient renseignées pour accéder à une base; pour des raisons pratiques, on ajoute PATH et LD_LIBRARY_PATH mais cela n'est pas indispensable.
Points d'attention
N/A.
Base de tests
Une base Oracle 19 multi-tenants.
Exemples
============================================================================================
Présentation
============================================================================================
Exécution du script
Les deux scripts s'exécutent de la façon suivante : . oraenv ou . coraenv
Attention à la syntaxe : "point" "espace" "nom_script_shell" et le .sh n'est pas obligatoire.
On peut les appeler de façon interactive ou non.
Interactive:
$ . oraenv
ORACLE_SID = [] ? orcl
Non-interactive (utile pour les scripts).
$ export ORACLE_SID=orcl
$ export ORAENV_ASK=NO
$ . oraenv
Deux fichiers différents ou deux exemplaires du même fichier?
A noter que ces fichiers ne sont pas des liens (pas de l en premier caractère quand on fait un ls -l). Dans les deux répertoires ils font la même taille mais leur date de création et leur propriétaire diffèrent. Pas d'extension .sh même si ce sont des scripts shell; néanmoins, dans l'en-tête du fichier oraenv, Oracle mentionne deux fois oraenv.sh.
[oracle@localhost bin]$ ls -l $ORACLE_HOME/bin/*oraenv*
-rwxr-xr-x. 1 oracle oinstall 6404 Jan 1 2000 /u01/app/oracle/product/version/db_1/bin/coraenv
-rwxr-xr-x. 1 oracle oinstall 6823 Jan 1 2000 /u01/app/oracle/product/version/db_1/bin/oraenv
[oracle@localhost bin]$ ls -l /usr/local/bin/*env*
-rwxr-xr-x. 1 root root 6404 May 31 2019 /usr/local/bin/coraenv
-rwxr-xr-x. 1 root root 6823 May 31 2019 /usr/local/bin/oraenv
Pour en avoir le coeur net (s'agit-il de liens ou non), j'ai modifié le fichier /u01/app/oracle/product/version/db_1/bin/oraenv en ajoutant #TEST sur la dernière ligne, après la partie "# Install any "custom" code here". Eh bien, le fichier /usr/local/bin/oraenv n'a pas été modifié... On voit bien avec ls -l que la taille entre les deux diffère de 5 octets, soit les 5 caractères que j'ai saisi.
[oracle@localhost ~]$ ls -l /usr/local/bin/oraenv
-rwxr-xr-x. 1 root root 6823 May 31 2019 /usr/local/bin/oraenv
[oracle@localhost ~]$ ls -l /u01/app/oracle/product/version/db_1/bin/oraenv
-rwxr-xr-x. 1 oracle oinstall 6828 Feb 11 03:40 /u01/app/oracle/product/version/db_1/bin/oraenv
Maintenant, la question est : lequel de ces deux fichiers est appelé? Je change mon code dans /u01/app/oracle/product/version/db_1/bin/oraenv en remplaçant #TEST par "echo "TEST"". Eh bien c'est /u01/app/oracle/product/version/db_1/bin/oraenv qui est exécuté quand je lance . oraenv
[oracle@localhost ~]$ . oraenv
ORACLE_SID = [orclcdb] ?
The Oracle base remains unchanged with value /u01/app/oracle
TEST
[oracle@localhost ~]$ . /u01/app/oracle/product/version/db_1/bin/oraenv
ORACLE_SID = [orclcdb] ?
The Oracle base remains unchanged with value /u01/app/oracle
TEST
[oracle@localhost ~]$ . /usr/local/bin/oraenv
ORACLE_SID = [orclcdb] ?
The Oracle base remains unchanged with value /u01/app/oracle
#
Exemple de variables d'environnement renseignées
[oracle@localhost ~]$ env | sort | grep -i oracle_
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/oracle/product/version/db_1
ORACLE_SID=orclcdb
ORACLE_UNQNAME=orclcdb
============================================================================================
Contenu du script $ORACLE_HOME/bin/oraenv
============================================================================================
Il date de 1991, soit 30 ans déjà; pour rappel, Oracle 7 est sorti en 1992.
[oracle@localhost bin]$ more oraenv
En-tête
#!/bin/sh
#
# $Header: buildtools/scripts/oraenv.sh /linuxamd64/6 2017/09/13 18:41:05 poosrini Exp $ oraenv.sh.pp Copyr (c) 1991 Oracle
#
# Copyright (c) 1991, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This routine is used to condition a Bourne shell user's environment
# for access to an ORACLE database. It should be installed in
# the system local bin directory.
#
# The user will be prompted for the database SID, unless the variable
# ORAENV_ASK is set to NO, in which case the current value of ORACLE_SID
# is used.
# An asterisk '*' can be used to refer to the NULL SID.
#
# 'dbhome' is called to locate ORACLE_HOME for the SID. If
# ORACLE_HOME cannot be located, the user will be prompted for it also.
# The following environment variables are set:
#
Les développeurs ont oublié la variable LD_LIBRARY_PATH.
# ORACLE_SID Oracle system identifier
# ORACLE_HOME Top level directory of the Oracle system hierarchy
# PATH Old ORACLE_HOME/bin removed, new one added
# ORACLE_BASE Top level directory for storing data files and
# diagnostic information.
#
# usage: . oraenv
#
# NOTE: Due to constraints of the shell in regard to environment
# ----- variables, the command MUST be prefaced with ".". If it
# is not, then no permanent change in the user's environment
# can take place.
#
#####################################
#
Petite erreur de syntaxe : aruments au lieu de arguments... rien de grave.
# process aruments
#
Partie SILENT
Réinitialisation à blanc de la variable SILENT puis recherche, parmi les arguments de oraenv, s'ils existent, de l'option -s. Si oui, alors SILENT est positionné à true. Dans ce cas, les messages du script oraenv ne seront pas affichés à l'écran puisqu'on souhaite être en mode silencieux.
SILENT='';
if [ $# -gt 0 ]; then
for arg in $@
do
if [ "$arg" = "-s" ]; then
SILENT='true'
fi
done
fi
Si la variable ORACLE_TRACE vaut T alors le script shell oraenv s'exécutera avec le mode trace ou debugging (c'est le résultat du set -x), c'est à dire que l'exécution du script sera détaillée à l'écran.
case ${ORACLE_TRACE:-""} in
T) set -x ;;
esac
#
# Determine how to suppress newline with echo command.
#
N=
C=
if echo "\c" | grep c >/dev/null 2>&1; then
N='-n'
else
C='\c'
fi
#
# Set minimum environment variables
#
# ensure that OLDHOME is non-null
if [ ${ORACLE_HOME:-0} = 0 ]; then
OLDHOME=$PATH
else
OLDHOME=$ORACLE_HOME
fi
Ci-dessous sont exportées les variables suivantes : ORACLE_SID, ORACLE_HOME, LD_LIBRARY_PATH, PATH, ORACLE_BASE.
Partie export ORACLE_SID
ORAENV_ASK est une variable pour rendre le script interactif ou non.
case ${ORAENV_ASK:-""} in #ORAENV_ASK suppresses prompt when set
NO) NEWSID="$ORACLE_SID" ;;
*) case "$ORACLE_SID" in
"") ORASID=$LOGNAME ;;
*) ORASID=$ORACLE_SID ;;
esac
echo $N "ORACLE_SID = [$ORASID] ? $C"
read NEWSID
case "$NEWSID" in
"") ORACLE_SID="$ORASID" ;;
*) ORACLE_SID="$NEWSID" ;;
esac ;;
esac
export ORACLE_SID
Partie export ORACLE_HOME
Appel à l'utilitaire dbhome pour obtenir, via le fichier oratab, le chemin du répertoire Oracle Home pour le Oracle SID saisi.
ORAHOME=`dbhome "$ORACLE_SID"`
case $? in
0) ORACLE_HOME=$ORAHOME ;;
*) echo $N "ORACLE_HOME = [$ORAHOME] ? $C"
read NEWHOME
case "$NEWHOME" in
"") ORACLE_HOME=$ORAHOME ;;
*) ORACLE_HOME=$NEWHOME ;;
esac ;;
esac
export ORACLE_HOME
Partie export LD_LIBRARY_PATH
#
# Reset LD_LIBRARY_PATH
#
case ${LD_LIBRARY_PATH:-""} in
*$OLDHOME/lib*) LD_LIBRARY_PATH=`echo $LD_LIBRARY_PATH | \
sed "s;$OLDHOME/lib;$ORACLE_HOME/lib;g"` ;;
*$ORACLE_HOME/lib*) ;;
"") LD_LIBRARY_PATH=$ORACLE_HOME/lib ;;
*) LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH ;;
esac
export LD_LIBRARY_PATH
Partie export PATH
Dans PATH, le répertoire $ORACLE_HOME/bin est ajouté, ce qui permet de lancer SQL*Plus et d'autres utilitaires Oracle sans avoir à saisir le chemin complet des programmes.
#
# Put new ORACLE_HOME in path and remove old one
#
case "$OLDHOME" in
"") OLDHOME=$PATH ;; #This makes it so that null OLDHOME can't match
esac #anything in next case statement
case "$PATH" in
*$OLDHOME/bin*) PATH=`echo $PATH | \
sed "s;$OLDHOME/bin;$ORACLE_HOME/bin;g"` ;;
*$ORACLE_HOME/bin*) ;;
*:) PATH=${PATH}$ORACLE_HOME/bin: ;;
"") PATH=$ORACLE_HOME/bin ;;
*) PATH=$PATH:$ORACLE_HOME/bin ;;
esac
export PATH
Partie gestion des ressources avec l'utilitaire ulimit
Linux, comme d’autres systèmes, attribue des limites par défaut aux processus et aux utilisateurs. Ces limites sont définies par l'utilitaire ulimit. Cela permet de s’assurer que l’OS reste disponible pour tous et ne vienne pas à crasher. Il permet aussi de connaître et/ou de modifier les les seuils haut et bas des ressources système allouées aux processus du système.
-------------------------------------------------------------------------------------
# Locate "osh" and exec it if found
ULIMIT=`LANG=C ulimit 2>/dev/null`
if [ $? = 0 -a "$ULIMIT" != "unlimited" ] ; then
if [ "$ULIMIT" -lt 2113674 ] ; then
Shell osh
Ici, Oracle appelle un programme osh; c'est un shell propriétaire Oracle, plus précisément un hack du shell Unix tcsh. Il a été créé pour implémenter dans un shell Unix des fonctionnalités de client Oracle et même pour pouvoir lancer des commandes SQL; faites une recherche sur Google, c'est un shell intéressant.
if [ -f $ORACLE_HOME/bin/osh ] ; then
exec $ORACLE_HOME/bin/osh
else
for D in `echo $PATH | tr : " "`
do
if [ -f $D/osh ] ; then
exec $D/osh
fi
done
fi
fi
fi
Partie export ORACLE_BASE
L'utilitaire orabase retourne un blanc plutôt que la valeur de ORACLE_BASE.
#set the value of ORACLE_BASE in the environment.
#
# Use the orabase executable from the corresponding ORACLE_HOME, since
# the ORACLE_BASE of different ORACLE_HOMEs can be different.
#
# If orabase can not determine a value then oraenv returns with either ORACLE_BASE
# as it was or set ORACLE_BASE to $ORACLE_HOME if it was not set earlier.
#
#
# The existing value of ORACLE_BASE is used to inform the user if the orabase
# determines the value of ORACLE_BASE. In case, oraenv can not determine a
# value then the user is informed with the previous ORACLE_BASE or with the
# $ORACLE_HOME.
ORABASE_EXEC=$ORACLE_HOME/bin/orabase
if [ ${ORACLE_BASE:-"x"} != "x" ]; then
OLD_ORACLE_BASE=$ORACLE_BASE
unset ORACLE_BASE
export ORACLE_BASE
else
OLD_ORACLE_BASE=""
fi
Suite de la partie export ORACLE_BASE
A noter que si la variable SILENT vaut true, tous les messages ci-dessous ne seront pas affichés. Quant aux actions de cette partie, les développeurs ont eu la bonne idée de mettre de nombreux commentaires.
Utilisation du fichier $ORACLE_HOME/install/orabasetab pour renseigner la variable ORACLE_BASE.
if [ -r $ORACLE_HOME/install/orabasetab ]; then
if [ -f $ORABASE_EXEC ]; then
if [ -x $ORABASE_EXEC ]; then
ORACLE_BASE=`$ORABASE_EXEC`
# did we have a previous value for ORACLE_BASE
if [ ${OLD_ORACLE_BASE:-"x"} != "x" ]; then
if [ $OLD_ORACLE_BASE != $ORACLE_BASE ]; then
if [ "$SILENT" != "true" ]; then
echo "The Oracle base has been changed from $OLD_ORACLE_BASE to $ORACLE_BASE"
fi
else
if [ "$SILENT" != "true" ]; then
echo "The Oracle base remains unchanged with value $OLD_ORACLE_BASE"
fi
fi
else
if [ "$SILENT" != "true" ]; then
echo "The Oracle base has been set to $ORACLE_BASE"
fi
fi
export ORACLE_BASE
else
if [ "$SILENT" != "true" ]; then
echo "The $ORACLE_HOME/bin/orabase binary does not have execute privilege"
echo "for the current user, $USER. Rerun the script after changing"
echo "the permission of the mentioned executable."
echo "You can set ORACLE_BASE manually if it is required."
fi
fi
else
if [ "$SILENT" != "true" ]; then
echo "The $ORACLE_HOME/bin/orabase binary does not exist"
echo "You can set ORACLE_BASE manually if it is required."
fi
fi
else
if [ "$SILENT" != "true" ]; then
echo "ORACLE_BASE environment variable is not being set since this"
echo "information is not available for the current user ID $USER."
echo "You can set ORACLE_BASE manually if it is required."
fi
fi
if [ ${ORACLE_BASE:-"x"} = "x" ]; then
if [ "$SILENT" != "true" ]; then
echo "Resetting ORACLE_BASE to its previous value or ORACLE_HOME";
fi
if [ "$OLD_ORACLE_BASE" != "" ]; then
ORACLE_BASE=$OLD_ORACLE_BASE ;
if [ "$SILENT" != "true" ]; then
echo "The Oracle base remains unchanged with value $OLD_ORACLE_BASE";
fi
else
ORACLE_BASE=$ORACLE_HOME ;
if [ "$SILENT" != "true" ]; then
echo "The Oracle base has been set to $ORACLE_HOME";
fi
fi
export ORACLE_BASE ;
fi
Customisation du script
Partie réservée aux dbas voulant ajouter leur code.
#
# Install any "custom" code here
#
============================================================================================
Le script oraenv en mode debug
============================================================================================
Exemple d'appel de oraenv en mode debug. Il faut mettre à T la variable ORACLE_TRACE. Notez le nombre de + devant chaque ligne : 2, 3 ou 4, représentant une hiérarchie dans le code exécuté.
[oracle@localhost ~]$ export ORACLE_TRACE=T
[oracle@localhost ~]$ . oraenv
++ N=
++ C=
++ grep --color=auto c
++ echo '\c'
++ N=-n
++ '[' /u01/app/oracle/product/version/db_1 = 0 ']'
++ OLDHOME=/u01/app/oracle/product/version/db_1
++ case ${ORAENV_ASK:-""} in
++ case "$ORACLE_SID" in
++ ORASID=orclcdb
++ echo -n 'ORACLE_SID = [orclcdb] ? '
ORACLE_SID = [orclcdb] ? ++ read NEWSID
++ case "$NEWSID" in
++ ORACLE_SID=orclcdb
++ export ORACLE_SID
+++ dbhome orclcdb
++ trap '' 1
++ RET=0
++ ORAHOME=
++ ORASID=orclcdb
++ ORASID=orclcdb
++ ORATAB=/etc/oratab
++ PASSWD=/etc/passwd
++ PASSWD_MAP=passwd.byname
++ case "$ORASID" in
++ test -f /etc/oratab
++ case "$ORASID" in
+++ awk -F: '{if ($1 == "orclcdb") {print $2; exit}}' /etc/oratab
++ ORAHOME=/u01/app/oracle/product/version/db_1
++ case "$ORAHOME" in
++ echo /u01/app/oracle/product/version/db_1
++ exit 0
++ ORAHOME=/u01/app/oracle/product/version/db_1
++ case $? in
++ ORACLE_HOME=/u01/app/oracle/product/version/db_1
++ export ORACLE_HOME
++ case ${LD_LIBRARY_PATH:-""} in
+++ sed 's;/u01/app/oracle/product/version/db_1/lib;/u01/app/oracle/product/version/db_1/lib;g'
+++ echo /u01/app/oracle/product/version/db_1/lib
++ LD_LIBRARY_PATH=/u01/app/oracle/product/version/db_1/lib
++ export LD_LIBRARY_PATH
++ case "$OLDHOME" in
++ case "$PATH" in
+++ sed 's;/u01/app/oracle/product/version/db_1/bin;/u01/app/oracle/product/version/db_1/bin;g'
+++ echo /home/oracle/Desktop/Database_Track/coffeeshop:/home/oracle/bin:/home/oracle/LDLIB:/u01/app/oracle/product/version/db_1/bin:/usr/sbin:/home/oracle/Desktop/Database_Track/coffeeshop:/home/oracle/java/jdk1.8.0_201/bin:/home/oracle/bin:/home/oracle/sqlcl/bin:/home/oracle/sqldeveloper:/home/oracle/datamodeler:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/oracle/sqlcl/bin:/home/oracle/sqldeveloper:/home/oracle/bin:/home/oracle/.local/bin:/home/oracle/bin
++ PATH=/home/oracle/Desktop/Database_Track/coffeeshop:/home/oracle/bin:/home/oracle/LDLIB:/u01/app/oracle/product/version/db_1/bin:/usr/sbin:/home/oracle/Desktop/Database_Track/coffeeshop:/home/oracle/java/jdk1.8.0_201/bin:/home/oracle/bin:/home/oracle/sqlcl/bin:/home/oracle/sqldeveloper:/home/oracle/datamodeler:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/oracle/sqlcl/bin:/home/oracle/sqldeveloper:/home/oracle/bin:/home/oracle/.local/bin:/home/oracle/bin
++ export PATH
+++ LANG=C
+++ ulimit
++ ULIMIT=unlimited
++ '[' 0 = 0 -a unlimited '!=' unlimited ']'
++ ORABASE_EXEC=/u01/app/oracle/product/version/db_1/bin/orabase
++ '[' /u01/app/oracle '!=' x ']'
++ OLD_ORACLE_BASE=/u01/app/oracle
++ unset ORACLE_BASE
++ export ORACLE_BASE
++ '[' -r /u01/app/oracle/product/version/db_1/install/orabasetab ']'
++ '[' -f /u01/app/oracle/product/version/db_1/bin/orabase ']'
++ '[' -x /u01/app/oracle/product/version/db_1/bin/orabase ']'
+++ /u01/app/oracle/product/version/db_1/bin/orabase
++ ORACLE_BASE=/u01/app/oracle
++ '[' /u01/app/oracle '!=' x ']'
++ '[' /u01/app/oracle '!=' /u01/app/oracle ']'
++ '[' '' '!=' true ']'
++ echo 'The Oracle base remains unchanged with value /u01/app/oracle'
The Oracle base remains unchanged with value /u01/app/oracle
++ export ORACLE_BASE
++ '[' /u01/app/oracle = x ']'
++ echo TEST
TEST
++ __vte_prompt_command
+++ sed 's/^ *[0-9]\+ *//'
+++ HISTTIMEFORMAT=
+++ history 1
++ local 'command=. oraenv'
++ command='. oraenv'
++ local 'pwd=~'
++ '[' /home/oracle '!=' /home/oracle ']'
+++ __vte_osc7
++++ __vte_urlencode /home/oracle
++++ LC_ALL=C
++++ str=/home/oracle
++++ '[' -n /home/oracle ']'
++++ safe=/home/oracle
++++ printf %s /home/oracle
++++ str=
++++ '[' -n '' ']'
++++ '[' -n '' ']'
+++ printf '\033]7;file://%s%s\007' localhost.localdomain /home/oracle
++ printf '\033]777;notify;Command completed;%s\007\033]0;%s@%s:%s\007%s' '. oraenv' oracle localhost '~' ''
[oracle@localhost ~]$