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

Hello cellmates, I'm about to convert some Unix shell scripts into Perl but have come up against what to me is a baffling problem - bear with me as my scripting knowledge is limited! As the scripts I'm converting are part of a package there are some constraints that I'm having to work within. The problem is that the shell script runs 2 scripts to set up the required environment. To make future upgrades simple I would prefer to call these scripts as a subroutine (their contents change with each new release) rather than transcribe them into Perl. The small test I've done for this produced unexpected results. I make system calls to both scripts which appear to work. I then print the ENV hash table contents to a file. I was shocked to discover that the changes apparently made by these scripts are not present (No $ORACLE_HOME etc). If I call these scripts from the command line the changes are there. Moreover if I run my script after calling these routines from the command line everything is as I would want it. The noddy test code follows:-

#!/usr/bin/perl -w # use strict ; use FileHandle ; # # SCALAR VARIABLES #-----------------# my $key = undef ; my $opfile = 'xxrc_env_details' ; my $result = 0 ; my $script = 'xxrcenvtest' ; my $value = undef ; my $footer = "\n\t\t***** End of Report *****\n\n" ; # # F O R M A T T I N G #-------------------# format XXRC_TOP = ENVIRONMENT Details for IHSLIVE . # format XXRC = @<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +<<<<<<<< $key, $value . # # P R O C E S S I N G #---------------------# # print "\n\t\t*** $script S T A R T S ***\n" ; # $result = system(". /opt/bin/oraIHSLIVE.env") ; # print "\n\tRES :: $result\n" ; if ($result) { print "\n\t\tRes :: $result\n" ; print "\n\t\tBombing Out (1)\n" ; exit 122 ; } # $result = system(". /opt/bin/fsw.env IHSLIVE") ; # if ($result) { print "\n\t\tRes :: $result\n" ; print "\n\t\tBombing Out (2)\n" ; exit 123 ; } # open XXRC, ">$opfile" or die "\n\tCanny Open $opfile :: $!\n" ; # # Formating code #--------------# select XXRC ; STDOUT->format_top_name("XXRC_TOP") ; STDOUT->format_name("XXRC") ; foreach $key (sort keys %ENV) { $value = $ENV{$key} ; write or die "\n\tyou hivnae goat this richt min! :: $!\n" ; } #STDOUT->format_name("XXRC_2") ; #write or die "\n\tyou hivnae goat this richt min! :: $!\n" ; select STDOUT ; print XXRC "$footer" or die "\n\tyou hivnae goat this richt min! :: $! +\n" ; close XXRC or die "Canny Close $opfile :: $!\n" ; print "\n\t\t*** $script E N D S ***\n\n\n" ;

Can I expect such calls to produce the environment that I want or do I have to convert the shell script into Perl? Have I missed the point about the interaction between the shell environment and Perls?
Cheers,
Ronnie

2006-04-29 Retitled by planetscape, as per Monastery guidelines
Original title: 'Envoronment variables?'

Replies are listed 'Best First'.
Re: set environment for parent process
by Corion (Patriarch) on Apr 28, 2006 at 12:36 UTC
      I may be missing the point of your reply (don't know why I made that a may?!) but the shell scripts I'm converting call these 2 scripts then run more code but all of this is in just 1 script. As such this environment doesn't exist until generated by the script at run time. It's not CRON related but job specific. Am I still not so much missing the boat as drowning? Be gentle.......

      Ronnie

        You said:

        The problem is that the shell script runs 2 scripts to set up the required environment.

        tilly's snippet does just that - it runs some script and extracts the environment that script sets up. This approach is the only approach under unixish shells by which you can get at whatever environment a script sets up when being sourced. Even though your script is not being run by cron, I think your problem is the same and is solved by tilly's approach.

        You'd have to read the referenced node and attempt to understand it to get the point of course...
Re: set environment for parent process
by sgifford (Prior) on Apr 28, 2006 at 18:02 UTC
    The problem you're running into is that environment variables that are set only apply to the process where they're set and any subprocesses. In this case, system creates a child process, the environment variables are set in that child process, then the child process exits. In the shell scripts, they're included with the "dot" operator or "source" command, which runs those scripts as if they were a part of the current script.

    Unfortunately there's no similarly easy mechanism in Perl, because the scripts are written in the shell scripting language, Perl doesn't include an interpreter for that language. Instead, you have to parse them yourself, as the example linked to above does; essentially it implements a very small and simplistic shell interpreter for the small subset of the shell language you're interested in (setting environment variables).