Re: how to set environmental vars
by ikegami (Patriarch) on Nov 10, 2005 at 20:53 UTC
|
sh scripts can only "source" sh scripts.
csh scripts can only "source" csh scripts.
Perl scripts can only "source" Perl scripts.
What we can do is have the run csh script and output its env variables in an easily parsable format. env can help us here. In fact, it can even be done without modifying the csh script — let's call it "script.csh" — using the following Perl code:
my $env = `csh -c 'source script.csh; env'`;
foreach my $line (split("\n", $env)) {
my ($key, $val) = split('=', $line, 2);
$ENV{$key} = $val;
}
Updated: I simplified my post by inlining the "wrapper script" into the executed command.
Updated: Added the closing backtick that was accidently deleted. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
I did not get your idea on using a wrapper script... can you please explain a bit more...
| [reply] [Watch: Dir/Any] |
|
I realized my post was hard to read so I updated it. I even removed the need for a wrapper script. Does that help?
| [reply] [Watch: Dir/Any] |
|
|
WRONG: environmental variables => RIGHT: environment variables
by merlyn (Sage) on Nov 10, 2005 at 21:42 UTC
|
Just for future Super Searchers, the proper term is environment variable, not environmental variable.
| [reply] [Watch: Dir/Any] |
Re: how to set environmental vars
by BUU (Prior) on Nov 10, 2005 at 21:01 UTC
|
To elaborate slightly, in linux land, processes can not change their parent's environment. Children typically inherit their parent's environment but when you exit a process, any changes you've made to the environment are lost. This means that when you use "system" to execute your CSH script, any changes it makes to the environment are lost when it exits and your perl script will never see it.
The best solution is to print your values to STDOUT or just have perl parse the CSH or some such. | [reply] [Watch: Dir/Any] |
Re: how to set environmental vars
by blue_cowdawg (Monsignor) on Nov 10, 2005 at 22:57 UTC
|
So, How do I source a env csh file and make sure.
Consider the following:
#!/usr/bin/perl -w
source_it() unless $ENV{foo};
printf "%s = %s\n",$_,$ENV{$_} foreach keys %ENV;
exit(0);
sub source_it{
exec "echo 'source env.csh ; perl $0' | csh -s";
}
I tested it, it works.
What I'm doing here is looking for a variable that I
know should have been set by the sourced in file and if
it isn't set I call the sub that execs off a "one-liner" to invoke csh, source in the environment and then re-execute the script. Once that
happens the variable I'm looking for is set and I just
continue to execute the script as planned. This will work
with ksh, bash, sh, with differing command line
switches.
This has the additional advantage is that in the event
one or more of the values is the result of a
scriplet or function buried in the sourced in file
it still works. Just parsing the setenv lines won't
make that happen.
Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
In your solution:
- There's a potential for an infinite loop.
- You're running one shell and one shell command more than you need.
- You're vulnerable to two injection attacks. (Only one fixed)
- You're not passing parent Perl's arguments to the child Perl. (Not fixed)
- You're not passing parent Perl's switches to the child Perl. (Not fixed)
Fix:
#!/usr/bin/perl -w
if (!defined($ENV{foo})) {
if (@ARGV > 0 && $ARGV[0] eq 'nested') {
die("Unable to find value for env var FOO\n");
}
exec 'csh', '-c', "source env.csh ; perl $0 nested";
die("Unable to execute csh: $!\n");
}
printf "%s = %s\n",$_,$ENV{$_} foreach keys %ENV;
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|
exec '/bin/csh', '-c', "source env.csh ; perl $0 nested";
|
|
You forgot about the issue of an executable being in
$PATH and being executed instead of the
shell we are after.
As far as an infinite loop is concerned I did state
that I am testing for a variable that I know exists
and is set in the env.csh file.
Fixing the last two bullet items you are referring to
is not covered in fix either AFAICT. Any arguments being
passed to the script are going to be lost. To fix that I'd
add
exec '/bin/csh', '-c', sprintf("source env.csh ; perl $0 nested %s"
+,join(" ",@ARGV));
And believe it or not there are still some ways to break
this...
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
Re: how to set environmental vars
by coreolyn (Parson) on Nov 10, 2005 at 20:54 UTC
|
Read your vars in from your file and populate the enviornment vie the %ENV hash
$ENV{'SHELLVAR') = $value
| [reply] [Watch: Dir/Any] [d/l] |
Re: how to set environmental vars
by polettix (Vicar) on Nov 10, 2005 at 20:55 UTC
|
You could start showing us what you tried exactly, i.e. the contents of the csh file and of the relevant piece of your Perl/CGI script that tries to "source" it.
Flavio
perl -ple'$_=reverse' <<<ti.xittelop@oivalf
Don't fool yourself.
| [reply] [Watch: Dir/Any] |
Re: how to set environment vars
by rsennat (Beadle) on Nov 11, 2005 at 10:03 UTC
|
Hi blue_cowdawg,
I get an error with the code, sorry if I miss anything silly.
#!/usr/bin/perl -w
if (!defined($ENV{foo})) {
if (@ARGV > 0 && $ARGV[0] eq 'nested') {
die("Unable to find value for env var FOO\n");
}
exec '/bin/csh', '-c', sprintf("source script1.csh ; perl $0 nested %s
+",join(" ",@ARGV));
die("Unable to execute csh: $!\n");
}
printf "%s = %s\n",$_,$ENV{$_} foreach keys %ENV;
The script1.csh
setenv PATH_ORIG "${PATH}"
setenv MANPATH_ORIG "${MANPATH}"
setenv LD_LIBRARY_PATH_ORIG "${LD_LIBRARY_PATH}"
And the Error I get is
Missing $ on loop variable at tmp.pl line 13.
Please help me out...
Thanks
| [reply] [Watch: Dir/Any] [d/l] [select] |