Clearing the Oracle environment in a Unix session

When working on servers with multiple ORACLE_HOMEs, keeping a session's Oracle-related environment variables in alignment is critical to an administrator's sanity. Different versions of the RDBMS or application server software can require different binaries and shared libraries, and different ORACLE_HOMEs may have different network setups. An improperly configured Oracle environment can lead to TNS errors when attempting to connect to a database ("Oh, it's trying to use that tnsnames.ora..."), restarts of the wrong app server ("Wait a minute, which opmnctl did I just run?"), or wasted weekend afternoons (I once sat on the phone w/ Oracle Support for 3 hours because $ORACLE_HOME/ctx/lib was not in my LD_LIBRARY_PATH. Good times!).

Oracle addresses the need for managing environment configuration with the 'oraenv' script, and with the various environment files that need to be sourced to work in the different contexts of Oracle Applications. Furthermore, a number of common utilities on the application server side of the world, such as emctl and opmnctl, are shell scripts that explicitly set the Unix environment before launching processes that do actual work. For some systems, however, these tools may not be enough. For example, the oraenv script does not set TNS_ADMIN, and does not remove any custom additions to the PATH environment variables that are based on a previous value of ORACLE_HOME.

Some simple solutions

There are a number of simple ways to prevent your Unix session environment from becoming a tangled mess of inappropriate paths, without resorting to setting individual environment variables manually, including:

  • Don't switch Oracle environments during a session. Instead, always start a new session to work in a new environment. This is can be good for maintaining personal discipline, but a bit tedious in practice, and besides, if I stopped there I wouldn't have much of a blog post, would I?
  • Create separate shell scripts to do the work of setting up the environment variables needed, appending or prepending Oracle-related values. This is a common practice, but after switching back and forth between environments a few times, the PATH environment variable can grow from this:
    /u01/app/oracle/product/client/10gR2/bin:/u01/app/oracle/product/client/10gR2/OPatch: 
    /u01/app/oracle/product/client/10gR2/opmn/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:
    /opt/oracle/bin

    ...to something like this admittedly contrived monstrosity:

    /u01/app/oracle/product/client/11gR1/bin:/u01/app/oracle/product/client/11gR1/OPatch:
    /u01/app/oracle/product/client/11gR1/opmn/bin:/u01/app/oracle/product/client/10gR2/bin:/u01
    /app/oracle/product/client/10gR2/OPatch:/u01/app/oracle/product/client/10gR2/opmn/bin:/u01/app
    /oracle/product/client/11gR1/bin:/u01/app/oracle/product/client/11gR1/OPatch:/u01/app/oracle/product
    /client/11gR1/opmn/bin:/u01/app/oracle/product/client/10gR2/bin:/u01/app/oracle/product/client
    /10gR2/OPatch:/u01/app/oracle/product/client/10gR2/opmn/bin:/usr/kerberos/bin:/usr/local/bin:/bin:
    /usr/bin:/opt/oracle/bin

    Alternately, instead of appending/prepending values to the environment variables, you could just reset them to default values, but those defaults may vary across servers, which can decrease portability of your scripts.

  • Unset all Oracle-related environment variables manually before setting up the new Oracle environment. This works well for things like ORACLE_HOME and TNS_ADMIN, but what about PATH and LD_LIBRARY_PATH? Doing 'unset PATH' is a surefire way to wreck a perfectly good session, and resetting PATH by copying only the elements you wish to preserve can be error-prone.

Another solution

I'd like to have a method to unset just the Oracle environment in my session; that is, it should remove references to the current ORACLE_HOME from the environment and leave other environment variables untouched. What I've settled on is the code shown below, which can be adapted into a shell function, dropped into an existing environment setup script, or placed in a standalone script:

#!/bin/bash
#Remove references to current ORACLE_HOME in various environment variables.
#Do nothing if ORACLE_HOME is not set

if [[ -n $ORACLE_HOME ]] 
then
   echo "Removing ORACLE_HOME references from environment"
   echo "Old ORACLE_HOME: $ORACLE_HOME"

   export LD_LIBRARY_PATH=`echo $LD_LIBRARY_PATH | sed "s#$ORACLE_HOME[^:]*:*##g"`
   # Include additional lines for clearing CLASSPATH, PERL5LIB, etc. as 
   # needed *before* modifying PATH

   export PATH=`echo $PATH | sed "s#$ORACLE_HOME[^:]*:*##g"`
   unset TNS_ADMIN ORACLE_HOME ORACLE_SID ORACLE_BASE
fi

Here's a demo:

[oracle@lyta ~]$ . setup_11gR1.env 
[oracle@lyta ~]$ echo $ORACLE_HOME; echo $LD_LIBRARY_PATH; echo $PATH
/u01/app/oracle/product/client/11gR1
/u01/app/oracle/product/client/11gR1/lib
/u01/app/oracle/product/client/11gR1/bin:/u01/app/oracle/product/client/11gR1/OPatch:/u01/app/oracle/product/client/11gR1/opmn/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/opt/oracle/bin
[oracle@lyta ~]$ . clear_oracle
Removing ORACLE_HOME references from environment
Old ORACLE_HOME: /u01/app/oracle/product/client/11gR1
[oracle@lyta ~]$ echo $ORACLE_HOME; echo $LD_LIBRARY_PATH; echo $PATH


/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/opt/oracle/bin

Since one person's completely sensible regular expression can be another person's incomprehensible line noise, here are some notes on the regex used in the sed command:

  • Uses # instead of the traditional / as a separator to prevent errors resulting from interpolation of the $ORACLE_HOME environment variable.
  • [^:]* matches zero or more non-colon characters. Since the colon is the separator for entries in the path, this prevents the regex from matching more than one entry at a time.
  • :* removes the colon from the end of a matched path entry, so the revised path doesn't contain a string of useless separators (:::::::).

I may have just presented a solution in search of problem. On the other hand, I've found this to be useful, so maybe you will, too. If so, please leave a glowingly grateful comment. If not, then I've just revealed myself to the entire Internet as a slightly obsessive geek. There's a first time for everything. ;-)

4 Comments

  1. Gary
    Posted 24 November 2008 at 18:22 | Permalink

    Can I recommend adding NLS variables to this too.
    Had an incident once where a script that ran fine from the command prompt buggered up from a scheduler tool because NLS_TERRITORY wasn't set there, which caused it to interpret to_char(date,'D') differently (whether the week starts on a Sunday or a Monday).

  2. Posted 24 November 2008 at 19:47 | Permalink

    Hi Gary,

    thanks for the comment; you make a very good point. Improperly set NLS variables have certainly caused headaches for me in the past. It's been a while since I've worked on a system where NLS variables had to be set differently on a per-ORACLE_HOME basis, which is probably why I neglected to include the NLS variables in my example. For completeness' sake, though, they should definitely be in there.

    Thanks for visiting!

    Regards,

    John P.

  3. Richard Bartholomew
    Posted 1 December 2008 at 9:09 | Permalink

    This was very timely for me as I've just started looking into the best way of controlling the Oracle environment. Having just modified your script to work on our AIX platform, I now need to decide the best way to set them up, ie separate script or modified oraenv! Any thoughts, please?

  4. Posted 1 December 2008 at 9:48 | Permalink

    Hi Richard,

    I suggest going for a separate script. I would definitely recommend against modifying the oraenv script itself, for two reasons:
    1) Doing so is almost certainly unsupported, and
    2) You risk having your changes overwritten by a patch.

    Thanks for visiting, and for the comment!

    Regards,

    John P.

One Trackback

  1. [...] Once you have your Ibex or Fedora up and running, check out Only Four Left, where John Piwowar has some tips for clearing the Oracle environment in a Unix session. [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*