Canalblog
Editer l'article Suivre ce blog Administration + Créer mon blog
Publicité
Blog d'un DBA sur le SGBD Oracle et SQL
11 février 2022

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 ~]$

Publicité
Publicité
Commentaires
Blog d'un DBA sur le SGBD Oracle et SQL
Publicité
Archives
Blog d'un DBA sur le SGBD Oracle et SQL
  • Blog d'un administrateur de bases de données Oracle sur le SGBD Oracle et sur les langages SQL et PL/SQL. Mon objectif est de vous faire découvrir des subtilités de ce logiciel, des astuces, voir même des surprises :-)
  • Accueil du blog
  • Créer un blog avec CanalBlog
Visiteurs
Depuis la création 340 405
Publicité