Håkon Hægland Håkon Hægland - 2 months ago 9
Perl Question

How to reload Bash environment variables inside Perl script?

Is there a way to load Bash environment variables ( defined by sourcing

~/.bashrc
from a Bash shell ) from within a Perl script. Specifically, I am interested in reloading the
PERL5LIB
environment variable in the case the caller of the Perl script is not a child of a
bash
process1. In that case,
$ENV{PERL5LIB}
will not exist, which will prevent me from using any modules I have installed in my home directory.

A first attempt could be to rerun my myself under
bash
with the
-l
option. This will load
~/.bash_profile
, and I have set that file up to load
~/.bashrc
.

#! /usr/bin/env perl

use strict;
use warnings;

if ( !exists $ENV{PERL5LIB} ) {
exec 'bash', '-lc', $0, @ARGV;
}
else {
# Main program starts here..
}


But this could enter an infinite loop for the (unexpected) case that
PERL5LIB
is not defined in
~/.bashrc
.

Footnotes:


[1] This specific case occured for me when trying to write a native host to be called from the
google-chrome
process using the Google Chrome Extension API.

Answer
#! /usr/bin/env perl

use strict;
use warnings;

BEGIN {
    if (!exists( $ENV{PERL5LIB} )) {    
        if (!@ARGV || $ARGV[0] ne '--no-restart') {
            exec('bash', '-lc', '"$@"', $0, $^X, $0, '--no-restart', @ARGV);
        }
    }

    if (@ARGV && $ARGV[0] eq '--no-restart') {
        shift(@ARGV);
    }
}

...

(Obviously, using Getopt::Long or some-such would be better.)

This not only meets your spec, but provides a bypass if needed.

That said, the whole concept is flawed. Most people shouldn't be using PERL5LIB, and it's not your job to fix badly configured systems (those that need PERL5LIB but don't have it set when it should be set).