Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Setting environment variables from a Perl script

Reply
Thread Tools

Setting environment variables from a Perl script

 
 
J. Romano
Guest
Posts: n/a
 
      06-29-2004
Dear Perl community,

In the past I have tried to find an answer to the question of how
to set environment variables in Perl scripts and make them last even
after the Perl script has finished. I eventually found the response
mentioned in "perldoc -q environment", which basically says that it
can't be done (although there are work-arounds if you're willing to
use a few Unix tricks).

However, I just recently discovered an easy way to do it. It works
like a charm in Unix. (But unfortunately, it doesn't work so great on
Win32.)

Basically, you write your script as normal, setting environment
variables, changing them, deleting them, and even changing
directories:

$ENV{EDITOR} = "/usr/bin/vi"; # make vi default editor
$ENV{PATH} .= ":/usr/bin/games"; # add games dir to path
delete $ENV{PAGER}; # remove the pager environment variable
chdir($ENV{HOME} . "/bin") or warn $!; # change to my bin dir

But at the end of the script, add this line:

exec $ENV{SHELL};

Run your script, and voila'! The environment variable changes stick!

I've found it's best to run your script with "exec" in front of it,
like so:

exec perl script.pl

otherwise, you'll have to type an extra "exit" for every time you run
the script in order to fully exit the shell.

Of course, this script assumes that your SHELL environment variable
exists and that it's set to your current shell.

In DOS using ActiveState Perl, I've found that changing:

exec $ENV{SHELL};

to:

system 'cmd';

works better than changing it to:

exec 'cmd';

(I have a hunch that ActivePerl implements the exec() call by
replacing it with system() and exit(), but I don't know for sure...)

As far as I know, in DOS you can't run the exec command, so you'll
have to type an extra "exit" to close down the DOS terminal window.
And deleting an evironment variable doesn't seem to work, either (at
least, not when I tried it). No error is generated; it just doesn't
appear to work.

So this approach doesn't fare so well in Win32 DOS, but it looks to
me that it works great in Unix. This goes against what the perldoc
says, so if anybody knows a caveat about using this technique (on
Unix) that I don't see, please speak up. But if there are no
problems, then I would think that this popular dilemma has been
solved.

Happy Perling!

-- Jean-Luc
 
Reply With Quote
 
 
 
 
A. Sinan Unur
Guest
Posts: n/a
 
      06-29-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (J. Romano) wrote in
news:(E-Mail Removed) om:

> Dear Perl community,
>
> In the past I have tried to find an answer to the question of how
> to set environment variables in Perl scripts and make them last even
> after the Perl script has finished. I eventually found the response
> mentioned in "perldoc -q environment", which basically says that it
> can't be done (although there are work-arounds if you're willing to
> use a few Unix tricks).


....

> But at the end of the script, add this line:
>
> exec $ENV{SHELL};
>
> Run your script, and voila'! The environment variable changes stick!


....

> This goes against what the perldoc says, so if anybody knows a
> caveat about using this technique (on Unix) that I don't see,
> please speak up. But if there are no problems, then I would
> think that this popular dilemma has been solved.
>
> Happy Perling!
>
> -- Jean-Luc


Jean-Luc:

This complete and utter nonsense: You have not changed the environment
variables in the shell from which you started your program. Instead, you
started a new shell with a new environment. That may be what you want but
then it very well may not be. The answer to the FAQ stands.


--
A. Sinan Unur
(E-Mail Removed) (reverse each component for email address)
 
Reply With Quote
 
 
 
 
J. Romano
Guest
Posts: n/a
 
      06-29-2004
> (E-Mail Removed) (J. Romano) wrote in
> news:(E-Mail Removed) om:
>
> > Dear Perl community,
> >
> > In the past I have tried to find an answer to the question of how
> > to set environment variables in Perl scripts and make them last even
> > after the Perl script has finished. I eventually found the response
> > mentioned in "perldoc -q environment", which basically says that it
> > can't be done (although there are work-arounds if you're willing to
> > use a few Unix tricks).

>
> ...
>
> > But at the end of the script, add this line:
> >
> > exec $ENV{SHELL};
> >
> > Run your script, and voila'! The environment variable changes stick!


"A. Sinan Unur" <(E-Mail Removed)> replied in message
news:<Xns9516EC0B3A600asu1cornelledu@132.236.56.8> ...
>
> This complete and utter nonsense: You have not changed the environment
> variables in the shell from which you started your program. Instead, you
> started a new shell with a new environment. That may be what you want but
> then it very well may not be. The answer to the FAQ stands.



Be careful what you call "complete and utter nonsense": The
perldoc explicitly says that "there is shell magic that may allow you
to fake it by eval()ing the script's output in your shell." That
solution probably suffers the same faults my solution has.
Nevertheless, it made it into the perldocs. (And if it doesn't happen
to have the same faults that render my own findings "complete and
utter nonsense", I'd be happy to see that solution.)

Of course, the changes made by my solution aren't permanent (in
that, once you exit your shell and restart it, the changes made by the
Perl script are no longer there), but there are times when a user
needs to set up the ideal environment in which to begin work on a
specific task (I've done it several times myself), but doesn't want
those environment changes to be permanent.

That scenario is what leads many Perl users to ask the question, "I
know how to change environment variables in Perl, but how do I made
them outlast my Perl program?" Mine is one such solution that doesn't
require "...shell magic that may allow you to fake it by eval()ing the
script's output in your shell." Not that there's anything wrong with
that; I just offer a different solution.

-- Jean-Luc
 
Reply With Quote
 
Keith Keller
Guest
Posts: n/a
 
      06-29-2004
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2004-06-29, J. Romano <(E-Mail Removed)> wrote:

> Of course, the changes made by my solution aren't permanent (in
> that, once you exit your shell and restart it, the changes made by the
> Perl script are no longer there), but there are times when a user
> needs to set up the ideal environment in which to begin work on a
> specific task (I've done it several times myself), but doesn't want
> those environment changes to be permanent.


Don't you think it's a bit overkill to use a Perl script to set
shell environment variables? Why not (for example) write a bash
script that accomplishes the same task?

- --keith

- --
http://www.velocityreviews.com/forums/(E-Mail Removed)-francisco.ca.us
(try just my userid to email me)
AOLSFAQ=http://wombat.san-francisco.ca.us/cgi-bin/fom

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFA4YZ5hVcNCxZ5ID8RAtubAKCVvzdTr2DBNYgkXI8ppG E5Cx+C3QCfXanq
j/xx/NsHf+etsB8ltzdF9pI=
=nqs1
-----END PGP SIGNATURE-----
 
Reply With Quote
 
J. Romano
Guest
Posts: n/a
 
      06-30-2004
> On 2004-06-29, J. Romano <(E-Mail Removed)> wrote:
>
> > Of course, the changes made by my solution aren't permanent (in
> > that, once you exit your shell and restart it, the changes made by the
> > Perl script are no longer there), but there are times when a user
> > needs to set up the ideal environment in which to begin work on a
> > specific task (I've done it several times myself), but doesn't want
> > those environment changes to be permanent.


Keith Keller <(E-Mail Removed)-francisco.ca.us> responded in
message news:<(E-Mail Removed)-francisco.ca.us>...
>
> Don't you think it's a bit overkill to use a Perl script to set
> shell environment variables?


That's a good question. I'll begin by saying that I used to write
shell scripts to do just that before I took the time to learn Perl. I
was able to write fairly elaborate scripts, but it was very
frustrating at times: between bash, csh, and ksh, I couldn't always
keep all the dialectual differences straight to the point that I had
trouble remembering how to do a simple loop or even a simple
assignment. In some cases, the shell language I started with lacked a
feature that another shell had, so I had to re-write my script from
scratch using the other shell language.

That's one of the reasons I liked Perl so much when I started
learning it. It had a superset of the shells' features in a syntax
that made sense to a C programmer.

> Why not (for example) write a bash script that accomplishes
> the same task?


Because the Perl script is much easier to write and understand.
I'll give you an example:

Back when I was a student in college, as part of our homework
assignments, we had to run a specific program the Unix machines. Many
times these programs required that certain environment variables were
set and, as a result, the instructors very often provided us with a
file for us to "source", like with the following command:

source cs400

That would set our environment variables (and maybe even change our
working directories). One of the environment variables that always
got modified was $PATH. As a result, my $PATH became super-huge, and
many of its entries were duplicates, making it difficult to
troubleshoot Unix problems as the $PATH was very convoluted.

I did not know Perl at the time, so I used csh to write myself a
script to simplify my $PATH. It worked, but it was not easy. Once I
had written the script, I could run a line like:

source simplifyPath

and duplicates would automatically be removed from my $PATH.

I don't remember how I wrote it, but I do remember that it was more
than five lines of code. And here's where Perl comes in: With this
Perl script that is effectively four lines long, I achieve the same
effect:


#!/usr/bin/perl -w
# File: simplifyPath.pl
use strict;
my %seen; # store paths already seen

my @pathList = split /:/, $ENV{PATH};
@pathList = grep { ! $seen{$_}++ } @pathList;
$ENV{PATH} = join ':', @pathList;

exec $ENV{SHELL};
__END__


Now, instead of typing "source simplifyPath", I type:

exec simplifyPath.pl

and I get a new $PATH that has all the duplicate paths removed.

Could I have done it with a bash script? Definitely. Like I said,
I've done it before with csh, but setting my environment variables and
my current directory with Perl gives me all the power of the Perl
programming language.

And this "Perl power" is why, periodically, we get users asking how
to use Perl to set environment variables that outlast the Perl script.
Unfortunately, most of them receive the answer that "it can't be
done." And that's the reason behind my posts -- to show that it CAN
be done.

I hope this answers your questions, Keith.

-- Jean-Luc
 
Reply With Quote
 
Darren Dunham
Guest
Posts: n/a
 
      07-07-2004
J. Romano <(E-Mail Removed)> wrote:
> So this approach doesn't fare so well in Win32 DOS, but it looks to
> me that it works great in Unix. This goes against what the perldoc
> says, so if anybody knows a caveat about using this technique (on
> Unix) that I don't see, please speak up. But if there are no
> problems, then I would think that this popular dilemma has been
> solved.


This isn't the same shell, but a new one. As a result, any shell
variables you may have set in the session will be lost.

$ BAR="bar bar"
$ echo "$FOO - $BAR"
- bar bar
$ exec /tmp/perl
execing /usr/bin/bash
$ echo "$FOO - $BAR"
foo foo -
$

Depending on your shell, you may lose history (although many will use a
..history file which will maintain state). You'd certainly lose any
connections to associated jobs.

$ sleep 500 &
[1] 2255
$ jobs
[1]+ Running sleep 500 &
$ exec /tmp/perl
execing /usr/bin/bash
$ jobs
$

I wouldn't call the issue "solved" by this technique. It's another
option.

--
Darren Dunham (E-Mail Removed)
Senior Technical Consultant TAOS http://www.taos.com/
Got some Dr Pepper? San Francisco, CA bay area
< This line left intentionally blank to confuse you. >
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
FAQ 8.34 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? PerlFAQ Server Perl Misc 0 03-12-2011 11:00 AM
sudo perl script with environment variables on linux powah Perl Misc 7 04-23-2009 02:00 AM
Setting an environment variable from another environment variable marcwentink@hotmail.com Java 5 04-04-2007 10:39 PM
Setting Environment Variables Rick Kasten Perl 2 07-07-2004 07:43 PM
Perl Help - Windows Perl script accessing a Unix perl Script dpackwood Perl 3 09-30-2003 02:56 AM



Advertisments