Re: Parsing variables from login scripts
by chromatic (Archbishop) on Jul 28, 2000 at 02:27 UTC
|
It's not too difficult... you just need split and a regex check. Something like the following is untested but conceptually fairly sound:
while (<INPUT>) {
chomp;
my ($var, $value) = split(/\s*=\s+/, $_, 2);
if ($value =~ s/^\$(\w+)//) {
# $value .= $env_var{$1} || '';
$value = $env_var{$1} . $value;
}
$env_var{$var} = $value;
}
You could make that shorter, but you could also add better checking to make it better. Jellybean actually does this in Jellybean::Config, so I know I've written it correctly at least once before.
Update: Don't work and post. Fastolfe is correct, and I've updated my code to work. | [reply] [d/l] |
|
|
I've been working way too many hours to see this clearly.
Here's what's not working so well, so far...
Ok, let's see if I can format this correctly:
___DATA___
MY_DIR=~/temp/module
export MY_DIR
MY_BIN=$MY_DIR/bin
MY_DATA=$MY_DIR/data
export MY_BIN MY_DATA
__temp.pl__
#! /usr/local/bin/perl
require "testpack.pm";
testpack::import();
print "DIR $DIR\n";
__testpack.pm__
package testpack;
sub import {
$conf_file = "conf.sh";
open (FILE, $conf_file) || die "Cant open file. \n";
while (<FILE>) {
if (! (/^\W/ || /^export/)) { # ign. cmnts & ws
chomp;
print "$_\n";
my ($var, $value) = split(/\s*=\s+/, $_, 2);
if ($value =~ s/^\$(\w+)//) {
$value .= $env_var{$1} || '';
}
$env_var{$var} = $value;
my ($caller_package) = caller;
*{"${caller_package}::${var}"} = $value;
} # end if
} # end while
} # END import() definition
| [reply] [d/l] |
|
|
Your split doesn't match your data -- the whitespace before the = is optional (zero or more instances) but required after the sign (one or more instances). Change the + to a * and it will probably work better.
You might put a debugging line after the split, just to see what's in $var and $value:
print "\$var is ->$var<-\t\$value is ->$value<-\n";
Besides that, I had things backwards in the original version of my code. Try this instead:
$value = $env_var{$1} . $value;
That way, it won't go in the wrong place. Oops!
| [reply] [d/l] [select] |
|
|
Shell-style variable interpolation has been discussed in recent nodes. The one you have above won't work at all like you seem to expect.
PATH = /someplace
PATH = $PATH:/somewhere/else
In this case, $env_var{PATH} would equal ":/somewhere/else/someplace".
I'm afraid I can't find the original thread, but a fairly robust regular expression looked something like this:
$value =~ s/$({?)(\w+)(?(1)})/$env_var{$2}/eg;
This would interpolate stuff like $PATH, ${PATH}, etc. | [reply] [d/l] [select] |
Re: Parsing variables from login scripts
by qi3ber (Scribe) on Jul 28, 2000 at 18:24 UTC
|
Of course, that'll take care of bash, ksh and other shells
that use the NAME = VALUE syntax for setting, but csh and
it's derivatives use a syntax like (set|setenv) NAME VALUE.
A major part of this code was taken from cromatic's
above, and then twisted in mischevious ways.
while (<DATA>) {
chomp;
my ($var, $value);
if ( /\s*(\w+)\s*=\s*([^;]+)/ || /\s*(?:set|setenv)\s+(\w+)\s+([^;
+]+)/ ) {
($var, $value) = ($1, $2);
} else {
next;
}
while ($value =~ /\\$/) {
my $temp .= <DATA>;
chomp $temp;
$temp =~ s/^\s*//;
$temp =~ s/\s*$//;
$value =~s/\\$/$temp/;
}
if ($value =~ s/^\$(\w+)//) {
$value .= $env_var{$1} || '';
}
$env_var{$var} = $value;
}
foreach my $key (keys %env_var) {
print "$key = $env_var{$key}\n";
}
__DATA__
NAME1 = VALUE1
set NAME2 = VALUE2
setenv NAME3 = VALUE3
NAME4=VALUE4 \
VALUE5
I Hope that that helps. | [reply] [d/l] |
RE: Parsing variables from login scripts
by eLore (Hermit) on Jul 28, 2000 at 20:42 UTC
|
sorry...
Thank you to all who posted... here's my working code:
package testpack;
# Setup Common Variables
sub import {
$conf_file = "conf.sh";
open (FILE, $conf_file) || die "Cant open file. \n";
while (<FILE>) {
if (! (/^\W/ || /^export/)) { # ignore irrelevants
chomp;
$var, $value) = split(/=/, $_, 2);
if ($value =~ s/^\$(\w+)//) {
$value = "$env_var{$1}$value" || '';
}
$env_var{$var} = $value;
my ($caller_package) = caller;
*{"${caller_package}::${var}"} = \$value;
} # end if
} # end while
} # END import() definition
1;
| [reply] [d/l] |
RE: Parsing variables from login scripts
by eLore (Hermit) on Jul 28, 2000 at 21:38 UTC
|
Now that I've gotten it partially working, I came upon a possibly better idea. The original thought was to have a perl script parse a .cshrc, .kshrc, or the like for variables. Would the better idea be to source the login/config script in a system call, and pipe the output of a UNIX env command into a hash? That way, all variables would be set exactly as they would occur in a shell. Thoughts? | [reply] |