Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to source a shell script [environment variables] in perl script without forking a subshell?

Tags:

shell

perl

I want to call "env.sh " from "my_perl.pl" without forking a subshell. I tried with backtics and system like this --> system (. env.sh) [dot space env.sh] , however wont work.

like image 785
Mandar Pande Avatar asked Jul 26 '11 11:07

Mandar Pande


1 Answers

Child environments cannot change parent environments. Your best bet is to parse env.sh from inside the Perl code and set the variables in %ENV:

#!/usr/bin/perl

use strict;
use warnings;

sub source {
    my $name = shift;

    open my $fh, "<", $name
        or die "could not open $name: $!";

    while (<$fh>) {
        chomp;
        my ($k, $v) = split /=/, $_, 2;
        $v =~ s/^(['"])(.*)\1/$2/; #' fix highlighter
        $v =~ s/\$([a-zA-Z]\w*)/$ENV{$1}/g;
        $v =~ s/`(.*?)`/`$1`/ge; #dangerous
        $ENV{$k} = $v;
    }
}

source "env.sh";

for my $k (qw/foo bar baz quux/) {
    print "$k => $ENV{$k}\n";
}

Given

foo=5
bar=10
baz="$foo$bar"
quux=`date +%Y%m%d`

it prints

foo => 5
bar => 10
baz => 510
quux => 20110726

The code can only handle simple files (for instance, it doesn't handle if statements or foo=$(date)). If you need something more complex, then writing a wrapper for your Perl script that sources env.sh first is the right way to go (it is also probably the right way to go in the first place).

Another reason to source env.sh before executing the Perl script is that setting the environment variables in Perl may happen too late for modules that are expecting to see them.

In the file foo:

#!/bin/bash

source env.sh

exec foo.real

where foo.real is your Perl script.

like image 164
Chas. Owens Avatar answered Sep 19 '22 13:09

Chas. Owens