unsetenv in the shell

S

Si

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?
 
K

Klaus

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.
+++++++++++++++++++++++++++++++++++++++++++
 
P

Peter J. Holzer

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
 
J

Jürgen Exner

Si said:
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

Jürgen Exner

Klaus said:
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
 
X

xhoster

Si said:
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.
 
U

Uri Guttman

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
 
S

szr

Uri said:
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 :)
 
B

Ben Morrow

[ local $ENV{FOO}; delete $ENV{FOO} ]
One more thing; the "delete" statement on line 10 is not needed:
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
 
S

szr

Ben said:
[ local $ENV{FOO}; delete $ENV{FOO} ]
One more thing; the "delete" statement on line 10 is not needed:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top