: 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