Perl: Sourcing a profile or bashrc or other shell script SOLVED

Everyone has worked at Perla place where they do things slightly different than what you’re used to. In this case we need to source a shell script file that houses the environment variables that we need to import. Unfortunately, the shell script file may or may not call other scripts/programs or it may use string manipulation to populate the environment variables. This means you can’t just read a the file in perl with simple key/value pairings.

In the Unix/Linux shell scripting world, if you export an environment variable it will be available in any child process.

# Here we export the variable so it will show up in Perl's %ENV hash:
export MYVAR="woohoo"

If we don’t explicitly export the environment variable, it will not be available to a child process.

# We don't export the variable so it will not show up in Perl's %ENV hash:
NOTEXPORTED_VAR="too bad"

So how do we handle the non-exported environment variables so Perl can use them? Each shell that is POSIX compliant in one way or another will have the set builtin command that will produce output of the environment variables regardless of whether they’ve been exported. Fortunately for us, it is in key/value pairs with an equals sign “=” as the delimiter. Be warned, you will get everything.

In the example code below we’re going to use the BASH shell to source the /somedir/.env file. You can replace it with the shell of your choice. Setting an environment variable with Perl’s %ENV hash will automatically export it making it available for any child processes of the Perl process.

 BEGIN {
     # you will need to include the "&& set" *IF* you have an shell file
     #  that doesn't export the variables.  
     if ( -f '/somedir/.env' && -x '/somedir/.env') {
         open(my $PS, 'bash -c ". /somedir/.env && set" |') or die 'Cannot execute bash built-in set');

         while (< $PS>) {
             # we need to strip extended ASCII characters
             #  and any lines without an "="
             if (/=/ && /[^\x20-\x7F]/) {
                 chomp;
                 my ($key, $value) = split /=/;
                 $ENV{$key} = $value;
             }
         }

         close $PS;
     }
Share Button