How can I properly import the environment from running a subcommand in Perl?

我们两清 提交于 2019-12-11 01:07:57

问题


In importing the environment from a subcommand, I want to add all environment variables exported from a bash script to a hash. When program gets run, it will set up some variables and export them. I'd like to save those variables in the Perl script for later. However I don't want to take the bash functions defined in the subcommand. Currently, I have a block like:

foreach (`program; env`)
{
    next if /^\(\)/;
    my ($a, $b) = split("=", $_);
    if( /^(\w+)=(.*)$/ ) {
        $hash{$1} = $2;    
    }
}

Is there a better way to do this? I'm not sure if matching the initial () is safe. Bonus points for handling newlines in environment variables, which I'm just closing my eyes for right now.


回答1:


I am assuming that the environment variables after program has executed are not same as the environment passed to it (which you can find in %ENV as explained in jeje's answer.

I am by no means knowledgeable about bash, so I am only going to address the part of the question about parsing the output of env.

#!/usr/bin/perl

use strict;
use warnings;

use autodie qw( open close );

$ENV{WACKO} = "test\nstring\nwith\nnewlines\n\n";

my %SUBENV;

open my $env_h, '-|', 'env';

my $var;

while ( my $line = <$env_h> ) {
    chomp $line;
    if ( my ($this_var, $this_val) = $line =~ /^([^=]+)=(.+)$/ ) {
        if ( $this_val =~ /^\Q()\E/ ) {
            $var = q{};
            next;
        }
        $var = $this_var;
        $SUBENV{ $var } = $this_val;
    }
    elsif ( $var ) {
        $SUBENV{ $var } .= "\n$line";
    }
}

use Data::Dumper;
print Dumper \%SUBENV;



回答2:


What you want is there: Shell-EnvImporter

An example:

  use Shell::EnvImporter;

  # Import environment variables exported from a shell script
  my $sourcer  = Shell::EnvImporter->new(
                   file => $filename,
                 );


  my $result = $sourcer->run() or die "Run failed: $@";



回答3:


This should be fine for getting all of the environment variables.

for(`program; env`){
  if( /^([^=]+)=(.*)$/ ) {
    $hash{$1} = $2;    
  }
}

If you want to start with a clean slate this might work better.

for(`env -i bash -c "program; env"`){
  next if /\(\)/;
  if( /^([^=]+)=(.*)$/ ) {
    $hash{$1} = $2;    
  }
}

env -i makes it's subcommand start off with a clean slate.

It calls bash with the -c argument, and the commands to run. We need to do that because otherwise the second env wouldn't get the environment variables from the program.



来源:https://stackoverflow.com/questions/1200849/how-can-i-properly-import-the-environment-from-running-a-subcommand-in-perl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!