how to source an environment file

D

dcruncher4

I want my perl script to read a file containing environment variables
and source it back
to the script. That is, when the script is executed, these variables
are not defined
in enviroment. Once the script starts, variables defined in that env
file is sourced
in. In korn shell we can do
dot(.) scriptname

How do we do the same in perl.

I found a crude approach. I do
system(". scriptname; env > /tmp/env.$$")
then I open /tmp/env.$$ file and store all env defined there
in $ENV{envvar}.

There should be a better way of doing it, shouldn't it?

thanks.
 
D

Dr.Ruud

(e-mail address removed) schreef:
I want my perl script to read a file containing environment variables
and source it back
to the script. That is, when the script is executed, these variables
are not defined
in enviroment. Once the script starts, variables defined in that env
file is sourced
in. In korn shell we can do
dot(.) scriptname

How do we do the same in perl.

I found a crude approach. I do
system(". scriptname; env > /tmp/env.$$")
then I open /tmp/env.$$ file and store all env defined there
in $ENV{envvar}.

There should be a better way of doing it, shouldn't it?

If you make that file look like
VAR1=test-A
VAR2="test B"
etc.

and then split per line on the first "=", you can update %ENV more
directly.

Or make it a shell-script that calls your perl-script last:

#!/bin/sh
VAR1=test-A
VAR2="test B"
myscript.pl

(untested)
 
A

anno4000

I want my perl script to read a file containing environment variables
and source it back
to the script. That is, when the script is executed, these variables
are not defined
in enviroment. Once the script starts, variables defined in that env
file is sourced
in. In korn shell we can do
dot(.) scriptname

How do we do the same in perl.

I found a crude approach. I do
system(". scriptname; env > /tmp/env.$$")
then I open /tmp/env.$$ file and store all env defined there
in $ENV{envvar}.

There should be a better way of doing it, shouldn't it?

You can use less shell and more Perl. You can also avoid the temp file.

my $env_dump = qx(
. scriptname;
perl -MData::Dumper -e'print Dumper \\ %ENV'
);

%ENV = %{ our $VAR1; eval $env_dump };

Anno
 
B

Brian McCauley

I want my perl script to read a file containing environment variables
and source it back
to the script. That is, when the script is executed, these variables
are not defined
in enviroment. Once the script starts, variables defined in that env
file is sourced
in. In korn shell we can do
dot(.) scriptname

How do we do the same in perl.

I always find this question ammuzing. The real, but totally unhelpful,
answer is that the nearest thing in Perl to Unix shells' "source"
command is do(FILE). Of course that expect the file to be in Perl just
as ksh expected it to be in ksh (and bash would expect it in bash and
sh would ....)
I found a crude approach. I do
system(". scriptname; env > /tmp/env.$$")
then I open /tmp/env.$$ file and store all env defined there
in $ENV{envvar}.

I think you can avoid the need for a temporary file with a pipe open.

open(my $env_fh, '|-','. scriptname; env') or die $!;
There should be a better way of doing it, shouldn't it?

Not really. If you want to execute a script written in another language
then somehow or other you are going to have to fire up and interpreter
for that laguage.

You can also exec a ksh interpreter and have that exec the perl
interpreter again. You do, of course, need to have an argument on your
second invocation of your script to tell it not to do this again!

Somthing like...

exec(". scriptname; exec $^X $0 -not_again ". join " ", map { quotemeta
} @ARGV );
 
C

Charles DeRykus

I want my perl script to read a file containing environment variables
and source it back
to the script. That is, when the script is executed, these variables
are not defined
in enviroment. Once the script starts, variables defined in that env
file is sourced
in. In korn shell we can do
dot(.) scriptname

How do we do the same in perl.

I found a crude approach. I do
system(". scriptname; env > /tmp/env.$$")
then I open /tmp/env.$$ file and store all env defined there
in $ENV{envvar}.

scriptname:
export DUM1=foo
...

perl -le 'BEGIN{ system(". /path/to/scriptname")== 0 or die "source
failed: $?}; use Env; print $ENV{DUM1};'
 
A

anno4000

Charles DeRykus said:
scriptname:
export DUM1=foo
..

perl -le 'BEGIN{ system(". /path/to/scriptname")== 0 or die "source
failed: $?}; use Env; print $ENV{DUM1};'

Did you test that?

Environment variables from .../scriptname will not become available. What
is "use Env" supposed to do?

Anno
 
C

Charles DeRykus

Did you test that?

Environment variables from .../scriptname will not become available. What
is "use Env" supposed to do?


Oops, sorry. A comedy of errors works well though if it's late, you
source scriptname before perl comes on the scene, you engage in some
shell sorcery , etc.
 
D

Dan Mercer

: I want my perl script to read a file containing environment variables
: and source it back
: to the script. That is, when the script is executed, these variables
: are not defined
: in enviroment. Once the script starts, variables defined in that env
: file is sourced
: in. In korn shell we can do
: dot(.) scriptname
:
: How do we do the same in perl.
:
: I found a crude approach. I do
: system(". scriptname; env > /tmp/env.$$")
: then I open /tmp/env.$$ file and store all env defined there
: in $ENV{envvar}.
:
: There should be a better way of doing it, shouldn't it?
:
: thanks.
:

Here's the source function from a module I wrote:

#!/usr/bin/perl -w
# Copyright Singing Pig Consulting 2005-
#
# Author Dan Mercer (Singing Pig Consulting)
# Date Created: 09/11/04 at 01:48:42 PM

use strict;
use warnings;

sub source
{
# Format: source file[,shell]
# : modifies the current environment

my ($srcfile, $shell, $legal, $srccmd, $pipeline, $perlcmd);
# filehandles
my ($hostsfh, $pipefh);
my $me = (caller(0))[3];

$srcfile = shift or die "$me: Missing source file argument\n";
$shell = shift or $shell = $ENV{SHELL} or $shell = "sh";
die "Unknown shell '$shell'\n" unless ($shell =~ /sh$/);

$srcfile = cwd() . "/" . $srcfile unless($srcfile =~ m{/});
# get full pathname
unless ($shell =~ m{^/})
{
my @path = split(/:/, $ENV{PATH});
foreach (@path)
{
next unless (-x "$_/$shell");
$shell = "$_/$shell";
last;
}
die "$me: unrecognized shell '$shell'\n" unless ($shell =~ m{^/});
}

# make sure it's a legal shell
$legal = 0;
if (open($hostsfh,"<","/etc/shells"))
{
while (<$hostsfh>)
{
chomp;
if ($_ eq $shell)
{
$legal = 1;
last;
}
}
close $hostsfh;
}
else
{
$legal = 1;
}

die "$me: illegal shell '$shell'\n" unless ($legal);
# determine source command
$srccmd = ($shell =~ /csh$/) ? "source" : ".";

# set up pipeline to source file then have perl print it out
# using NUL's as file and record separators
$perlcmd = "$^X -l0 -e '" . '\$,=\$\\;print %ENV' . "'";
$pipeline = "$shell -c \"$srccmd $srcfile;$perlcmd\"";
open ($pipefh, "$pipeline |") or die "$me: pipeline failed - $!\n";

my @env = %ENV;

local $/ = "\0"; # IRS to NUL - use local so WHHSH
my @newenv = <$pipefh>;
chomp @newenv;
push @env,@newenv;
close $pipefh;

%ENV = @env;
}
__DATA__

Dan Mercer
 
D

Dan Mercer

: I want my perl script to read a file containing environment variables
: and source it back
: to the script. That is, when the script is executed, these variables
: are not defined
: in enviroment. Once the script starts, variables defined in that env
: file is sourced
: in. In korn shell we can do
: dot(.) scriptname
:
: How do we do the same in perl.
:
: I found a crude approach. I do
: system(". scriptname; env > /tmp/env.$$")
: then I open /tmp/env.$$ file and store all env defined there
: in $ENV{envvar}.
:
: There should be a better way of doing it, shouldn't it?
:
: thanks.
:

Here's the source function from a module I wrote:

#!/usr/bin/perl -w
# Copyright Singing Pig Consulting 2005-
#
# Author Dan Mercer (Singing Pig Consulting)
# Date Created: 09/11/04 at 01:48:42 PM

use strict;
use warnings;

sub source
{
# Format: source file[,shell]
# : modifies the current environment

my ($srcfile, $shell, $legal, $srccmd, $pipeline, $perlcmd);
# filehandles
my ($hostsfh, $pipefh);
my $me = (caller(0))[3];

$srcfile = shift or die "$me: Missing source file argument\n";
$shell = shift or $shell = $ENV{SHELL} or $shell = "sh";
die "Unknown shell '$shell'\n" unless ($shell =~ /sh$/);

$srcfile = cwd() . "/" . $srcfile unless($srcfile =~ m{/});
# get full pathname
unless ($shell =~ m{^/})
{
my @path = split(/:/, $ENV{PATH});
foreach (@path)
{
next unless (-x "$_/$shell");
$shell = "$_/$shell";
last;
}
die "$me: unrecognized shell '$shell'\n" unless ($shell =~ m{^/});
}

# make sure it's a legal shell
$legal = 0;
if (open($hostsfh,"<","/etc/shells"))
{
while (<$hostsfh>)
{
chomp;
if ($_ eq $shell)
{
$legal = 1;
last;
}
}
close $hostsfh;
}
else
{
$legal = 1;
}

die "$me: illegal shell '$shell'\n" unless ($legal);
# determine source command
$srccmd = ($shell =~ /csh$/) ? "source" : ".";

# set up pipeline to source file then have perl print it out
# using NUL's as file and record separators
$perlcmd = "$^X -l0 -e '" . '\$,=\$\\;print %ENV' . "'";
$pipeline = "$shell -c \"$srccmd $srcfile;$perlcmd\"";
open ($pipefh, "$pipeline |") or die "$me: pipeline failed - $!\n";

my @env = %ENV;

local $/ = "\0"; # IRS to NUL - use local so WHHSH
my @newenv = <$pipefh>;
chomp @newenv;
push @env,@newenv;
close $pipefh;

%ENV = @env;
}
__DATA__

Dan Mercer
 
D

Dan Mercer

: I want my perl script to read a file containing environment variables
: and source it back
: to the script. That is, when the script is executed, these variables
: are not defined
: in enviroment. Once the script starts, variables defined in that env
: file is sourced
: in. In korn shell we can do
: dot(.) scriptname
:
: How do we do the same in perl.
:
: I found a crude approach. I do
: system(". scriptname; env > /tmp/env.$$")
: then I open /tmp/env.$$ file and store all env defined there
: in $ENV{envvar}.
:
: There should be a better way of doing it, shouldn't it?
:
: thanks.
:

Here's the source function from a module I wrote:

#!/usr/bin/perl -w
# Copyright Singing Pig Consulting 2005-
#
# Author Dan Mercer (Singing Pig Consulting)
# Date Created: 09/11/04 at 01:48:42 PM

use strict;
use warnings;

sub source
{
# Format: source file[,shell]
# : modifies the current environment

my ($srcfile, $shell, $legal, $srccmd, $pipeline, $perlcmd);
# filehandles
my ($hostsfh, $pipefh);
my $me = (caller(0))[3];

$srcfile = shift or die "$me: Missing source file argument\n";
$shell = shift or $shell = $ENV{SHELL} or $shell = "sh";
die "Unknown shell '$shell'\n" unless ($shell =~ /sh$/);

$srcfile = cwd() . "/" . $srcfile unless($srcfile =~ m{/});
# get full pathname
unless ($shell =~ m{^/})
{
my @path = split(/:/, $ENV{PATH});
foreach (@path)
{
next unless (-x "$_/$shell");
$shell = "$_/$shell";
last;
}
die "$me: unrecognized shell '$shell'\n" unless ($shell =~ m{^/});
}

# make sure it's a legal shell
$legal = 0;
if (open($hostsfh,"<","/etc/shells"))
{
while (<$hostsfh>)
{
chomp;
if ($_ eq $shell)
{
$legal = 1;
last;
}
}
close $hostsfh;
}
else
{
$legal = 1;
}

die "$me: illegal shell '$shell'\n" unless ($legal);
# determine source command
$srccmd = ($shell =~ /csh$/) ? "source" : ".";

# set up pipeline to source file then have perl print it out
# using NUL's as file and record separators
$perlcmd = "$^X -l0 -e '" . '\$,=\$\\;print %ENV' . "'";
$pipeline = "$shell -c \"$srccmd $srcfile;$perlcmd\"";
open ($pipefh, "$pipeline |") or die "$me: pipeline failed - $!\n";

my @env = %ENV;

local $/ = "\0"; # IRS to NUL - use local so WHHSH
my @newenv = <$pipefh>;
chomp @newenv;
push @env,@newenv;
close $pipefh;

%ENV = @env;
}
__DATA__

Dan Mercer
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top