Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

How to change a script's environment after the script is already run, based on shell sourcing ?

by ronbarak (Novice)
on Sep 28, 2006 at 08:28 UTC ( #575303=perlquestion: print w/ replies, xml ) Need Help??
ronbarak has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I have a Perl script that relies on $ENV{'ORACLE_HOME'}.

However, it may be that the account I run the script under has not set $ORACLE_HOME.

The setting of $ORACLE_HOME in the shell is performed by executing (sourcing) the following in .bashrc of the account: . /etc/profiles/bashrc.ora.v.10 (it contains lines like: "<b>export ORACLE_BASE=/oracle</b> and <b>export ORACLE_HOME=$ORACLE_BASE/v10.2.0</b> depending on the Oracle version).

My question is, how can I source '/etc/profiles/bashrc.ora.v.10' in my Perl script, and have the results inserted in the script's current environment ?

Note: I cannot just write $ENV{ORACLE_HOME}='/oracle/v10.2.0' ;, as the Oracle version is not known to my script.

Thanks,

Ron.

Comment on How to change a script's environment after the script is already run, based on shell sourcing ?
Select or Download Code
Re: How to change a script's environment after the script is already run, based on shell sourcing ?
by Corion (Pope) on Sep 28, 2006 at 08:33 UTC

    tilly wrote Get default login environment, and the discussion shows some changes to the script. This is what you want, except that you will likely not want the default login environment but instead your Oracle setup script.

      If the environment hasn't been set up in the shell, then parsing "bash --env" isn't going to help him. He needs to parse the env-file itself.

      --rjray

        Uh - I was thinking of instead just running the login shell running the login shell and then sourcing the file-to-be-sourced, and then dumping env:

        perl -e '$env = `/bin/ksh -c ". /vol1/osabst/.wms_profile; env"`; prin +t $env'

        The process of parsing that output is the same as the process of parsing the login environment.

        Update: s/\sset/env/, as per shmem's comment

Re: How to change a script's environment after the script is already run, based on shell sourcing ?
by rjray (Chaplain) on Sep 28, 2006 at 08:42 UTC

    Assuming you have the filename ahead of time, just parse it yourself:

    our $file = '/etc/profiles/bashrc.ora.v.10'; open my $fh, "< $file" or die "open: $!"; while (defined($_ = <$fh>)) { next unless /^export\s+([A-Za-z]\w+)=(.*)$/; $ENV{$1} = $2; } close($fh);

    --rjray

      That would probably work fine for a majority of cases, where the shell script for environment setup tends to be pretty simple and explicit. It's a good-enough solution when you know enough about the shell script to trust that it will work.

      But I can easily imagine (and have seen) examples where the value assigned to a relevant exported variable refers to some other shell variable that was set previously in the same file (and not necessarily exported), or is the output of some back-ticked command, or other arcane cleverness. For shell scripts like that, you really don't want this approach.

        True, but the original author hinted that the file contained only simple environment variables in the vein of ORACLE_SID and similar.

        There's probably a CPAN module already that handles the special cases and back-ticks, in fact...

        --rjray

Re: How to change a script's environment after the script is already run, based on shell sourcing ?
by tweetiepooh (Friar) on Sep 28, 2006 at 10:19 UTC
    On my Oracle systems there is a file /var/opt/oracle/oratab. This associates ORACLE_SID to a home directory and has the general form
    SID:ORACLE_HOME:<Y|N>
    The last bit is where the database gets started at boot time.

    Now I only have one database but I do run scripts via cron whereby the environment isn't always correct. I then set ORACLE_HOME and ORACLE_SID in a <BEGIN> block or just in the script. Both seem to work.

    With Sybase I seem to need a conditional bit of code that checks for the environment variable SYBASE and if not existing then sets it and execs the script over itself. This may be needed to point to different libraries but with Oracle you should only need one set of libraries to use as the client even if connecting to a different database.

    I guess I could write a wrapper shell script but that then means two files to maintain.

Re: How to change a script's environment after the script is already run, based on shell sourcing ?
by sgifford (Prior) on Sep 28, 2006 at 15:56 UTC
    Here's a more flexible way, which will work even if the environment file contains shell commands:
    #!/usr/bin/perl print "Starting...\n"; use constant ENVSCRIPT => '/etc/profiles/bashrc.ora.v.10'; if (!$ENV{ORACLE_HOME} && !$ENV{SKIP_ENVSCRIPT}) { $ENV{SKIP_ENVSCRIPT}=1; exec("/bin/sh -c '. @{[ENVSCRIPT]}; exec $0'"); } print "ORACLE_HOME=$ENV{ORACLE_HOME}\n";

    If $ENV{ORACLE_HOME} is unset, it runs a copy of the shell to first source the environment file, then re-execute your script. $ENV{SKIP_ENVSCRIPT} keeps this from looping if there are problems.

    One caveat is that if the script is run like perl your_script.pl the exec may not work. If that's how you normally call your script, you should be able to adjust the shell line to take that into account.

Re: How to change a script's environment after the script is already run, based on shell sourcing ?
by brian_d_foy (Abbot) on Sep 28, 2006 at 19:08 UTC

    It seems to me the answers given so far are too complicated because everyone wants to write Perl where they don't need it. You want a shell script instead. Source the environment file to set up the environment, then start the Perl script.

    #!/bin/sh source /etc/profiles/bashrc.ora.v.10 perl program.pl

    And, if your Perl program is already running and the profile file has changed, you can exec the script again, effectively starting fresh.

    --
    brian d foy <brian@stonehenge.com>
    Subscribe to The Perl Review

      Minor point: I'd add "exec" in front of "perl". Reduces overhead a minor bit. It's sorta like the the goto &NAME in Perl, but bigger.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://575303]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (15)
As of 2014-07-31 13:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (248 votes), past polls