unsetenv in the shell

Discussion in 'Perl Misc' started by Si, Mar 2, 2008.

  1. Si

    Si Guest

    hi, i have a perl program that calls another application. this second
    application uses the value of certain environment variables during its
    operation. i'm having trouble with unsetting those variables during
    the course of the perl script.

    my (wrong) pseudo code:

    $var1 = $ENV{'VAR1};
    $var2 = $ENV{'VAR2'};
    $var3 = $ENV{'VAR3'};

    system( "unsetenv VAR1");
    system( "unsetenv VAR2");
    system( "unsetenv VAR3");

    run_the_external_app;

    system( "setenv VAR1 $var1");
    system( "setenv VAR2 $var2");
    system( "setenv VAR3 $var3");


    can someone tell me what the correct syntax should be for this?
     
    Si, Mar 2, 2008
    #1
    1. Advertising

  2. Si

    Klaus Guest

    On Mar 2, 10:00 am, Si <> wrote:
    > hi, i have a perl program that calls another application. this second
    > application uses the value of certain environment variables during its
    > operation. i'm having trouble with unsetting those variables during
    > the course of the perl script.
    >
    > $var1 = $ENV{'VAR1};
    > $var2 = $ENV{'VAR2'};
    > $var3 = $ENV{'VAR3'};
    >
    > system( "unsetenv VAR1");
    > system( "unsetenv VAR2");
    > system( "unsetenv VAR3");
    >
    > run_the_external_app;


    Environment variables will be restored to their original state after a
    system call, therefore whatever system("unsetenv...") (or any other
    system() call for that matter) does to the environment variables has
    no effect whatsoever on the environment variables of the running perl
    program, this includes the effect on any subsequent actions in the
    running perl program, such as "run_the_external_app;"

    However, if you are running under Unix, perlfaq 8 might be helpful:

    +++++++++++++++++++++++++++++++++++++++++++
    ++ perlfaq 8:
    ++ ----------
    ++ "I {changed directory, modified my environment} in a
    ++ perl script. How come the change disappeared when I
    ++ exited the script? How do I get my changes to be
    ++ visible?"
    ++
    ++ Unix: In the strictest sense, it can't be done--the script
    ++ executes as a different process from the shell it was
    ++ started from. Changes to a process are not reflected in
    ++ its parent--only in any children created after the change.
    ++ There is shell magic that may allow you to fake it by
    ++ eval()ing the script's output in your shell; check out the
    ++ comp.unix.questions FAQ for details.
    +++++++++++++++++++++++++++++++++++++++++++

    --
    Klaus
     
    Klaus, Mar 2, 2008
    #2
    1. Advertising

  3. On 2008-03-02 09:36, Klaus <> wrote:
    > On Mar 2, 10:00 am, Si <> wrote:
    >> hi, i have a perl program that calls another application. this second
    >> application uses the value of certain environment variables during its
    >> operation. i'm having trouble with unsetting those variables during
    >> the course of the perl script.
    >>
    >> $var1 = $ENV{'VAR1};
    >> $var2 = $ENV{'VAR2'};
    >> $var3 = $ENV{'VAR3'};
    >>
    >> system( "unsetenv VAR1");
    >> system( "unsetenv VAR2");
    >> system( "unsetenv VAR3");
    >>
    >> run_the_external_app;

    >
    > Environment variables will be restored to their original state after a
    > system call,


    That's wrong. The variables will not be restored after the call, they
    never change.

    system( "unsetenv VAR1");
    starts a second process which then tries to execute the "unsetenv"
    program, which probably doesn't exist ("unsetenv" is a builtin command
    of the csh). But even if program was a shell which could unset
    environment variables (try system("unset VAR1;");) it would only unset
    it's own copy of the variable, never the variable of the perl process.

    hp
     
    Peter J. Holzer, Mar 2, 2008
    #3
  4. Si <> wrote:
    >
    >hi, i have a perl program that calls another application. this second
    >application uses the value of certain environment variables during its
    >operation. i'm having trouble with unsetting those variables during
    >the course of the perl script.
    >
    >my (wrong) pseudo code:
    >
    >$var1 = $ENV{'VAR1};
    >$var2 = $ENV{'VAR2'};
    >$var3 = $ENV{'VAR3'};
    >
    >system( "unsetenv VAR1");
    >system( "unsetenv VAR2");
    >system( "unsetenv VAR3");


    "Unsetting" an environment variable is in no way different from setting it.
    Your case is a variation of the FAQs:
    I {changed directory, modified my environment} in a perl script. How come
    the change disappeared when I exited the script? How do I get my changes to
    be visible?

    Just do those changes in the script itself instead of in a child process
    (perldoc -f delete)

    jue
     
    Jürgen Exner, Mar 2, 2008
    #4
  5. Klaus <> wrote:
    >On Mar 2, 10:00 am, Si <> wrote:
    >> system( "unsetenv VAR1");

    >
    >Environment variables will be restored to their original state after a
    >system call,


    Actually they are never modified for the parent process in the first place.

    jue
     
    Jürgen Exner, Mar 2, 2008
    #5
  6. Si

    Guest

    Si <> wrote:
    > hi, i have a perl program that calls another application. this second
    > application uses the value of certain environment variables during its
    > operation. i'm having trouble with unsetting those variables during
    > the course of the perl script.
    >
    > my (wrong) pseudo code:
    >
    > $var1 = $ENV{'VAR1};
    > $var2 = $ENV{'VAR2'};
    > $var3 = $ENV{'VAR3'};
    >
    > system( "unsetenv VAR1");
    > system( "unsetenv VAR2");
    > system( "unsetenv VAR3");
    >
    > run_the_external_app;
    >
    > system( "setenv VAR1 $var1");
    > system( "setenv VAR2 $var2");
    > system( "setenv VAR3 $var3");
    >
    > can someone tell me what the correct syntax should be for this?


    Others have explained why this doesn't work. By adding an extra scope
    and a local, you can avoid having to explicitly store the old values.

    {
    my @del=qw/VAR1 VAR2 VAR3/;
    local %ENV{@del};
    delete %ENV{@del};

    run_the_external_app;

    };

    Once the outer scope exits, the variables will automatically be reset.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Mar 3, 2008
    #6
  7. Si

    Uri Guttman Guest

    >>>>> "x" == xhoster <> writes:

    x> Others have explained why this doesn't work. By adding an extra scope
    x> and a local, you can avoid having to explicitly store the old values.

    x> {
    x> my @del=qw/VAR1 VAR2 VAR3/;
    x> local %ENV{@del};
    x> delete %ENV{@del};


    technically those should be @ENV{@del} as they are hash slices. but i
    think perl allows % there.

    x> Once the outer scope exits, the variables will automatically be reset.

    definitely the best way to do this.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Architecture, Development, Training, Support, Code Review ------
    ----------- Search or Offer Perl Jobs ----- http://jobs.perl.org ---------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Mar 3, 2008
    #7
  8. Si

    szr Guest

    Uri Guttman wrote:
    >>>>>> "x" == xhoster <> writes:

    >
    > x> Others have explained why this doesn't work. By adding an extra
    > scope x> and a local, you can avoid having to explicitly store the
    > old values.
    >
    > x> {
    > x> my @del=qw/VAR1 VAR2 VAR3/;
    > x> local %ENV{@del};
    > x> delete %ENV{@del};
    >
    >
    > technically those should be @ENV{@del} as they are hash slices. but i
    > think perl allows % there.


    I get:

    $ perl -v | head -n 2 | tail -n 1
    This is perl, v5.8.8 built for i686-linux-64int-ld


    $ ./test_clpm_env_0001.pl
    syntax error at ./test_clpm_env_0001.pl line 9, near "%ENV{"
    syntax error at ./test_clpm_env_0001.pl line 10, near "%ENV{"
    Execution of ./test_clpm_env_0001.pl aborted due to compilation errors.
    You have new mail in /var/spool/mail/root


    $ nl -b a -n rn -w 3 -s ' ' test_clpm_env_0001.pl | head -n 10 | tail -n
    2
    9 local %ENV{@var_list};
    10 delete %ENV{@var_list};


    If I changed those lines to have @ENV{... instead of %ENV{... it works
    as expected.

    * * *

    One more thing; the "delete" statement on line 10 is not needed:

    $ nl -b a -n rn -w 3 -s ' ' test_clpm_env_0001.pl
    1 #!/usr/local/bin/perl
    2
    3 use strict;
    4
    5 my @var_list = qw/VAR1 VAR2 VAR3/;
    6 @ENV{@var_list} = qw/X1 Y2 Z3/;
    7
    8 {
    9 local @ENV{@var_list};
    10 #delete @ENV{@var_list};
    11
    12 #run_the_external_app;
    13 print "[", join(', ', @ENV{@var_list}), "]\n";
    14 };
    15 print "[", join(', ', @ENV{@var_list}), "]\n";


    $ ./test_clpm_env_0001.pl
    [, , ]
    [X1, Y2, Z3]


    Reemmber that the "local" statement gives a temporary copy of %ENV which
    is in a clean state, making the "delete" unnecessary :)

    --
    szr (mmmmm.., Perl)
     
    szr, Mar 3, 2008
    #8
  9. Si

    Ben Morrow Guest

    Quoth "szr" <>:
    >

    [ local $ENV{FOO}; delete $ENV{FOO} ]
    >
    > One more thing; the "delete" statement on line 10 is not needed:

    <snip>
    >
    > Reemmber that the "local" statement gives a temporary copy of %ENV which
    > is in a clean state, making the "delete" unnecessary :)


    This is not the case. local sets the value to undef, which in the case
    of %ENV is translated to the empty string. An empty environment variable
    is very different from one which isn't there:

    ~% perl -le'$ENV{FOO} = 1; local $ENV{FOO}; system "env"' | grep FOO
    FOO=

    Ben
     
    Ben Morrow, Mar 3, 2008
    #9
  10. Si

    szr Guest

    Ben Morrow wrote:
    > Quoth "szr" <>:
    >>

    > [ local $ENV{FOO}; delete $ENV{FOO} ]
    >>
    >> One more thing; the "delete" statement on line 10 is not needed:

    > <snip>
    >>
    >> Reemmber that the "local" statement gives a temporary copy of %ENV
    >> which is in a clean state, making the "delete" unnecessary :)

    >
    > This is not the case. local sets the value to undef, which in the case
    > of %ENV is translated to the empty string. An empty environment
    > variable is very different from one which isn't there:
    >
    > ~% perl -le'$ENV{FOO} = 1; local $ENV{FOO}; system "env"' | grep
    > FOO FOO=


    Excellent point. I view %ENV as a tied hash of sorts.

    --
    szr
     
    szr, Mar 3, 2008
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    5,731
    Jonathan Bromley
    Feb 18, 2005
  2. Christian Heimes
    Replies:
    0
    Views:
    606
    Christian Heimes
    Feb 27, 2008
  3. Gerardo Herzig
    Replies:
    1
    Views:
    1,089
    Philipp Pagel
    Feb 27, 2008
  4. D'Arcy J.M. Cain
    Replies:
    0
    Views:
    869
    D'Arcy J.M. Cain
    Feb 27, 2008
  5. Samuel A. Falvo II
    Replies:
    0
    Views:
    487
    Samuel A. Falvo II
    Oct 8, 2008
Loading...

Share This Page