blink has asked for the wisdom of the Perl Monks concerning the following question:

I need to execute ". <some-file> from within a Perl script. he problem is, is that it doesn't execute using system, ` `, or exec.

Just in case someone may ask, "test.out" does get opened and written to, this code executes as root, "oraenv" is an executable with sufficient privileges.

Here's the code:

#!/usr/bin/perl -w use strict; my ( $ScriptName, $TAG ); my $file = "/export/home/scratch/test.out"; my $oratabFile = "/var/opt/oracle/oratab"; my $date = `/bin/date`; open ORATAB, "<$oratabFile" or die "$!\n"; open FILE, ">>$file" or die "$!\n"; my ( $host, $sid, $type ) = split ( '\_', $ENV{NB_ORA_PC_SCHED} ); while ( my $oraLine = <ORATAB> ) { chomp $oraLine; my ( $oraSID, $oraHome, $oraType ) = split ( '\:', $oraLine ); if ( $oraSID = $sid ) { $ENV{ORACLE_HOME} = $oraHome; $ScriptName = "$oraSID" . '_' . "$type.sh"; $TAG = $ENV{NB_ORA_PC_SCHED}; } } $ENV{ORAENV_ASK} = "NO"; $ENV{ORACLE_SID} = $sid; `export ORAENV_ASK ORACLE_SID ORACLE_HOME`; system(". /apps/oracle/bin/oraenv"); #################################### # # # Begin loop which will determine # # what type of backup to run # # # #################################### print FILE "\n\n\n"; print FILE "$ENV{NB_ORA_PC_SCHED} is a COLD backup"; print FILE "\n\n\n"; print FILE "====================================================\n"; print FILE "Printing environmental vars for troubleshooting\n"; print FILE "====================================================\n"; print FILE "\n\n\n"; print FILE `/usr/ucb/printenv`; print FILE "\n\n\n"; print FILE "====================================================\n"; print FILE "End Troubleshooting Section\n"; print FILE "====================================================\n"; print FILE "\n\n\n"; close ORATAB; close FILE;

Replies are listed 'Best First'.
Re: How to execute a Korn shell ". <some-file>" from within Perl
by sauoq (Abbot) on Jan 30, 2003 at 06:18 UTC

    You seem to be misunderstanding two things.

    1. Perl starts a new shell each time you call system or use backticks.
    2. A child process cannot modify the environment of its parent process. (This is generally regarded as a good thing.)
    Keep those two things in mind and you'll understand why lines like `export ORAENV_ASK ORACLE_SID ORACLE_HOME`; are completely useless. It simply doesn't make sense to start a shell, export some envariables (which haven't even been set), and then exit the shell.

    You can use a method such as runrig suggested; run a child process and then copy the child's environment into perl's. Or you can just set perl's environment in the first place. If you can be sure your shell script won't contain anything but simple variable assignments, parsing it directly wouldn't be too difficult. (Be forewarned that you'll be forever limited in the complexity of the shell script though.)

    Finally, you also should keep in mind that perl uses /bin/sh to execute commands in backticks or when you call system with a single argument that contains shell metacharacters. Unless /bin/sh is really a Korn shell in your environment you should be careful of compatibility issues.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: How to execute a Korn shell ". <some-file>" from within Perl
by helgi (Hermit) on Jan 30, 2003 at 09:58 UTC
    The problem is, is that it doesn't execute using system, ` `, or exec.

    Yes, it does. Your "problem" is that a child process cannot set environment variables for its parents. This is as it should be.

    Read perldoc -q environment for details.

    You need to find out which environment variables your child process is setting and then set them from within Perl using $ENV{SOME_VAR}='some value'; or set them permanently using your .login script or some such mechanism, depending on shell and OS.

    --
    Regards,
    Helgi Briem
    helgi AT decode DOT is

Re: How to execute a Korn shell ". <some-file>" from within Perl
by runrig (Abbot) on Jan 30, 2003 at 03:23 UTC
    Run your command, then run printenv, capture the output, and set the environment variables from within perl (untested):
    /^(\w+)=(.*)/ and $ENV{$1} = $2 for qx( . oraenvcommand printenv );
    This breaks on variables with newlines in the value...

    Update: Told you it was untested. Fixed code. Still untested. As suggested below, it would be better to run the command before your perl script executes, if at all possible.

      Thanks for the reply, but it didn't work. It's still not executing.