Parent Process Environment
Ronnie
created: 2006-05-02 05:40:36
I'm trying to use the code Tilly supplied re picking up an environment from a parent process - I tried this some time ago but time was pressing so I ended up just creating the environment by copying the details from the shell script into my own Perl version....tedious beyond belief! I'm now working on a much bigger application who's default environment is created by 2 shell scripts and would be WAY too tiresome to replicate. I think I know what her script does but wondered if the error I'm getting is as a result of how our environment looks.

Sample
OLDHOME=${ORACLE_HOME}	;	export	OLDHOME
unset	TWO_TASK;
ORACLE_SID=IHSLIVE	;	export	ORACLE_SID
ORACLE_BASE=/ihs/tpp/oracle/live	;	export	ORACLE_BASE
ORACLE_DOC=${ORACLE_BASE}/doc	;	export	ORACLE_DOC
ORACLE_HOME=${ORACLE_BASE}/9.2.0	;	export	ORACLE_HOME
ORACLE_PAGER=/usr/bin/pg	;	export	ORACLE_PAGER
ORACLE_LPSTAT=/usr/bin/lpstat	;	export	ORACLE_LPSTAT
ORACLE_LPPROG=/usr/bin/lp	;	export	ORACLE_LPPROG
ORACLE_LPARGS='-o	nobanner'	;	export	ORACLE_LPARGS
#

Yes before anyone else tells me, it's a mess but it's supplied by a third party and we are NOT allowed to change it.....
The code I'm using for test purposes is -
#!/usr/bin/perl -w
#
use strict ;
#
sub get_login_env {
  local %ENV;
#  my $shell = shift || (getpwuid($<))[8];
#
#  I know that the shell we use is the ksh
#
#
  my $shell = '/bin/ksh' ;
  my $env = `echo env | perl -e 'exec {"$shell"} -sh'`;
  if (wantarray) {
    my @pieces = ($env =~ m/^(.*?)=((?:[^\n\\]|\\.|\\\n)*)/gm );
    s/\\(.)/$1/g foreach @pieces;
    return @pieces;
  }
  else {
    return $env;
  }
}
#
# Variables
#----------#

my $result = undef ;

# Processing
#----------#

print "\n\t\tPlay with ENV starts\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 ;
}
#
%ENV = (%ENV, get_login_env());

print "\n\t\tPlay with ENV ends\n" ;
This produces an error which I'm guessing may be caused by the format of our packages environment.The error generated is
$ xxrc_pickup_env.pl
 
                Play with ENV starts
 
        RES :: 0
Environment variable ADMIN_DIR is not set
grep: can't open a
grep: can't open tty
 
                Play with ENV ends
Ignoring the ADMIN_DIR message - well we do apparently! - does this mean that tilly's code won't work with the format of our environment? If so I suppose I better get typing....for the next X days!
Re: Parent Process Environment
created: 2006-05-02 05:56:01
Instead of parsing the script, couldn't you just run it, and list the environment values at the end? You can do that by running another script in the same [doc://system] or [doc://qx] call. Something like this (untested — well, the perl oneliner has been tested):
my $env = `envscript.sh && perl -MData::Dumper -e '$Data::Dumper::Terse=1; print Dumper \%ENV'`;
You can then [eval] the string representation of the anonymous hash you captured into $env. You may have to suppress output from the shell script.

And on some platforms, %ENV is magical, so you might not be able to pick up the whole environment. All you can do, is test.

Re: Parent Process Environment
created: 2006-05-02 11:03:58

We solved a similar issue pretty much backwards from you. And, from the sounds of it, you may not have the freedom to do this, but others who read this may, so I'll write it down for posterity.

Over the last 5 years, we have moved from a shell-based automation system to a perl-based one. However, there was an intermediate stage where it was hybrid, and we needed to do likewise: share a bunch of variables. Lots of variables. Hundreds of them, actually.

What we did was move all the variables to perl. Move, not copy. Actually, we moved them to a data file (e.g., XML) that perl would read and parse. The reader was one module, the parser another. And then we wrote a shim program that would call all the readers (which would call all the parsers) and eventually gather all the information that the shell scripts might need. This actually would take a few seconds. And then it would spit out a shell script with a bunch of "VAR=value\nexport VAR" text.

We tore out all the variable setting from the shell scripts, and replaced it with three lines:

  ./generate_shell.pl [...] > /tmp/automation-$$
  . /tmp/automation-$$
  rm /tmp/automation-$$
It wasn't cheap to do this, but it was worth it when we could guarantee that only one value of a variable existed in our environment, and by changing that one, centralised value, we knew that everyone that needed it would have the right value.

Since then, we've managed to replace the rest of the shell code, and the shim is gone. But it helped a lot for the phase we were in.

perlmonks.org content © perlmonks.org and bart, Ronnie, Tanktalus

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03