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

I need to run several programs that depend on Environmental Variables (found in %ENV) in a row. I need to set various values in %ENV that is passed to these programs that I am running using backticks (to catch the output). I would like to do this so that the %ENV changes are only local to the script being run at the time and not actually change the ENV values present.

I tried this:
print "$ENV{'TERM'}\n"; { $ENV{'TERM'} = "foo"; print "$ENV{'TERM'}\n"; } print "$ENV{'TERM'}\n";

the result should be:
vt100 foo vt100

but it was this instead:
vt100 foo foo

When this program was done the actual value of TERM was not changed when i checked from a commandline. Is there a better way to set ENV variables for programs being run from a perl script?

Replies are listed 'Best First'.
Re: Changing ENV values locally
by ivancho (Hermit) on Jul 01, 2005 at 19:01 UTC
    a program cannot change the outside environment - thus, after the program was done, the environment is back to original.

    for the localizing of %ENV, try

    print $ENV{TERM}; { local %ENV = %ENV; $ENV{TERM} = "bla"; print `echo \$TERM`; } print $ENV{TERM};
Re: Changing ENV values locally
by davidrw (Prior) on Jul 01, 2005 at 18:54 UTC
    Your snippet wouldn't work because %ENV is a global variable, so when you change it in the inner scoper (inside the curlies) you're changing it outside, too. To localize the change, you can maybe do local %ENV; inside the inner block.

    It's also possible You may also just want to save the value and reset it later..
    my $save_term = $ENV{TERM}; $ENV{TERM} = "foo"; print `echo a \$TERM`; $ENV{TERM} = $save_term;
    Update: rephrased to lessen the emphasis on the second (non-local) solution which is just an example of another possibility and not an advocation of the 'right' (or even 'good') way.
      Your code example is an excellent demonstration of exactly what the local keyword does. Except you don't have to pick a name like save_term for the old version of the value.

      --
      [ e d @ h a l l e y . c c ]

        I know you know this, but it's worth mentioning another big advantage of local over the hand-coded equivalents exampled by your respondee.

        The programmer (or another at some later time) may modify the code such that it returns without restoring the original value.

        With local, this won't happen. The programmer might forget, but the compiler/interpreter will not.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
Re: Changing ENV values locally
by bart (Canon) on Jul 01, 2005 at 20:56 UTC
    Try
    print "$ENV{'TERM'}\n"; { local $ENV{'TERM'} = "foo"; print "$ENV{'TERM'}\n"; } print "$ENV{'TERM'}\n";
Re: Changing ENV values locally
by sgifford (Prior) on Jul 01, 2005 at 22:43 UTC
    In addition to the options here, you can set the environment on the command-line:
    $var = `env TERM=foo set`;
Re: Changing ENV values locally
by ambrus (Abbot) on Jul 02, 2005 at 16:28 UTC

    Perl is not TeX.