Re: .env loading the dot env file?
by arpad.szasz (Pilgrim) on Mar 28, 2021 at 17:36 UTC
|
| [reply] |
|
This seems to be exactly the thing I was looking for.
| [reply] |
Re: .env loading the dot env file?
by Corion (Patriarch) on Mar 28, 2021 at 09:08 UTC
|
See Get default login environment and the discussion therein. There is Shell::EnvImporter.
I'm not sure if you really want the effects of a shell script, or just something that "looks like sh environment commands". If so, your approach seems good, but doesn't respect quoted constructs.
In your code, I would at least change the split() to a more robust parser, so that it also understands foo=bar=baz as setting foo to bar=baz:
#my ($key, $value) = split /\s*=\s*/, $line;
if( $line =~ /^\s*([^=]+)=(.*?)\s*$/ ) {
my ($key,$value) = ($1,$2);
$ENV{$key} = $value;
} else {
croak "Malformed environment line: '$line'";
};
Support for foo="bar=baz" and foo=\"bar=baz\" would also be addable, but if you want to support multiline values, you'll have to switch away from line-based parsing.
Updated: The capturing parentheses were missing for the key, spotted by Anomalous Monk | [reply] [d/l] [select] |
|
| [reply] |
|
It is definitely not "best practice" to parse config files of any format that is not your own in an ad hoc way. It's a last resource if you can't figure out the format or proper way to use it for affecting your environment externally to your Perl program; that said, if you have to do it you have to do it. Try not to, though.
| [reply] |
Re: .env loading the dot env file?
by hippo (Archbishop) on Mar 28, 2021 at 09:32 UTC
|
It depends how complicated/rigorous you want to make it. I would probably start from Config::General as with features like -InterPolateEnv and -AllowMultiOptions you can get much of the functionality and configurability built-in.
I have seen the .env file mentioned in several applications and environments
It might be helpful to know which ones. Just a thought.
| [reply] [d/l] [select] |
|
| [reply] |
Re: .env loading the dot env file?
by LanX (Saint) on Mar 28, 2021 at 18:41 UTC
|
maybe tangential, but it's pretty easy to "source" a foreign rc-file (here bash) from Perl with this trick
my $bashcode=<<'__bash__';
. /tmp/src.sh;
perl -MData::Dumper -e 'print Dumper \%ENV';
__bash__
my $VAR1;
eval qx{bash -c "$bashcode"};
print $VAR1->{MONK};
original discussion: Re^3: How to "source" a shell file in Perl? (Trojan Dump)
| [reply] [d/l] |
|
Very nice. The benefit here is that you don't have to do anything externally when invoking your script. Thank you and bookmarked :)
| [reply] |
|
Yes I like this inside-out approach too, since it's trivial to share data between different languages. :)
BUT I should add that source has the same limitation like a do config.pl ... it's evaling code which might pose a bigger security problem than only "parsing" the file.
OTOH that's also the case if the shell does it, before executing Perl.
It wasn't clear to me what kind of .env the OP wants. And %ENV is always security relevant.
| [reply] [d/l] [select] |
Re: .env loading the dot env file?
by Haarg (Priest) on Mar 28, 2021 at 15:54 UTC
|
As far as a standard goes: I've investigated parsers for the "dotenv" format in other languages, and I'm pretty sure no two of them had compatible parsing. Possibly the rust parser was strict enough that it would either parse the same as a shell, or fail to parse.
I have a module about 80% done that would parse all of the variants I found, and allow editing the files without losing order or comments. But of course the last 20% takes too much effort and I haven't found the motivation to complete it.
| [reply] |
Re: .env loading the dot env file? -- module
by Discipulus (Canon) on Mar 28, 2021 at 12:44 UTC
|
Hello szabgab,
just once we play vice versa: I write and you read ;)
I dont know this being a standard, nor I know if it is wise.. but why dont use directly perl instead?
Adapting my Modules as configuration files you can have ( in modconfenv.pm ):
use strict;
use warnings;
$ENV{XX} = 42;
$ENV{YY} = 'whatever you wont';
unshift @ARGV,$_ for reverse
map {s/\s*#.*$|^\s*#.*$//; (split ' ',$_,2)}
split /\n/, <<'EOCONF'
--put here your
--list of arguments and
#any
#indented
--comment #comments
--too
EOCONF
;
print "@ARGV" unless caller;
1;
and then just perl -Mmodconfenv -e "print qq($ENV{XX} $ENV{YY})"
L*
There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
| [reply] [d/l] [select] |
Re: .env loading the dot env file?
by perlfan (Parson) on Mar 28, 2021 at 18:32 UTC
|
.env is not standard in any traditional shell I am aware of, but that set is limited to: sh/bash and csh/tcsh.
If the format of that file indicates a standard shell "rc" type file with (for Bourne style), then I would not attempt to read it in your Perl program since it can contain anything the shell supports. The following is deceptive because it's just a basic shell script:
VAR="some value"
export VAR
Rather, source it before your Perl program is invoked. This will do the right thing, and be available in %ENV.
If it's an ini format, use something like Config::Tiny - or whatever module is appropriate for the serialization format. Because that's all it is; don't invent your own. you would not do this for JSON, YAML, or XML - I hope :)
A few notes about understanding the %ENV in your Perl program; and assuming we're dealing strictly within the same process space on the same machine, etc:
- your entire environment is available to a perl process under which it is invoked via %ENV
- modifying %ENV in your program is respected by the current process and all child processes created by it (including via system, fork etc
- child processes can affect their own env and that of their
ancestors descendants, but not of their parent - even if you export - this means when your program returns from running to your interactive shell (e.g.,) the environment will not have changed based on anything your program did (and it can't)
- best practice is to localize %ENV if you plan on mucking with it in your perl program, e.g., local %ENV = %ENV; - this is so you can control the scope of the changes in the same process using Perl's built in scoping; in other words, it allows you to "go back" to the original %ENV or at least only affect it in very precise parts of your program; as noted above, it is not needed to "protect" your interactive shell's environment once the program has returned
The last thing I'll end with is, don't parse files that are meant to affect your shell environment in Perl. Use the shell to source it; then invoke your program.
HTH | [reply] [d/l] [select] |