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

Page 661 of Camel III states:

"Setting a value in %ENV changes the environment for both your process and child processes..."

However, perlvar(1) for both v5.6.1 and v6.8.0 both state:

"Setting a value in ENV changes the environment for any child processes you subsequently fork() off."

It appears from my testing as though setting %ENV does not change the current process, at least on Solaris.

My questions are:

1) Can somebody confirm the expected behaviour? Is it platorm-specific, or does this never work?

2) If it does not work, why not? To put it another way, why should Perl not support changing the environment of the current process?

3) If it does not work, I need a workaround. Wrapping each of my Perl programs in a shell script which sets the environment seems messy. I used to require users to source an environmental setup script, but this polluted their environment unnecessarily. All ideas welcome.

Cheers Kevin

Replies are listed 'Best First'.
Re: Setting env vars in current process
by tachyon (Chancellor) on Feb 11, 2003 at 19:15 UTC

    Works fine on Win2K

    C:\>type test.pl # grab the first ENV var name we find for ( keys %ENV ) { $key = $_; last; } # reset ENV var print "Resetting $key, was $ENV{$key}\n"; $ENV{$key} = 'new value'; # fork my $pid = fork(); # confess print $pid ? "Parent has $key:$ENV{$key}\n" : "Child has $key:$ENV{$ke +y}\n"; C:\>perl test.pl Resetting PROMPT, was $P$G Parent has PROMPT:new value Child has PROMPT:new value C:\>

    And on Redhat 7.3

    [root@www root]# cat test.pl # grab the first ENV var name we find for ( keys %ENV ) { $key = $_; last; } # reset ENV var print "Resetting $key, was $ENV{$key}\n"; $ENV{$key} = 'new value'; # fork my $pid = fork(); # confess print $pid ? "Parent has $key:$ENV{$key}\n" : "Child has $key:$ENV{$ke +y}\n"; [root@www root]# perl test.pl Resetting _, was /usr/bin/perl Parent has _:new value Child has _:new value [root@www root]#

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Hmm, thanks. Your test works fine for me also. I think there must be another problem. Basically, the LD_LIBRARY_PATH of the parent shell points at libxml (C library) v2.4.22, whereas my Perl program uses a Lib::XML which only works with libxml v2.4.24 and above. So, in my Perl program, I set LD_LIBRARY_PATH to libxml v2.4.24 in a BEGIN block. However, this does not seem to be having the desired effect. Maybe I am missing something... Cheers Kevin

        It might be too late. The loader that loaded perl is probably the same loader that's loading your shared libraries. It has already initialized and is no longer looking for that environment variable. You probably have to set the variable before invoking perl.

        --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
Re: Setting env vars in current process
by jdporter (Paladin) on Feb 11, 2003 at 19:19 UTC
      Nope, I only wanted to change the current process env. People seem pretty confident that you can do this. (So was I until just now!!) As discussed in reply above, I will just have to work out what else is wrong with my setting LD_LIBRARY_PATH for XML::LibXML. Cheers Kevin
        Perhaps you should have shown some code.
        If you're doing something like
        $ENV{'LD_LIBRARY_PATH'} = '/...'; use XML::LibXML;
        then the problem may be that the envar isn't getting set until after the library gets loaded. In which case, try
        BEGIN { $ENV{'LD_LIBRARY_PATH'} = '/...'; } use XML::LibXML;

        jdporter
        The 6th Rule of Perl Club is -- There is no Rule #6.

Re: Setting env vars in current process
by fruiture (Curate) on Feb 11, 2003 at 19:18 UTC

    That sentence in perlvar does not mean "changing %ENV only changes the environment of all children", it's more like "note that this will change the envirnonment of all your children".

    Relax and test it, %ENV represents the current environmental variables of your process, without caveats.

    #!/usr/bin/perl $ENV{FOO} = 1; print "\$ENV{FOO} is $ENV{FOO} still\n"; exec( '/usr/bin/env' );

    The output of env will also mention "FOO" being "1".

    --
    http://fruiture.de
      Ok, thanks. That's what I thought. I must be missing something else then (see reply above). Will reply if/when I find out!