如何在Perl中运行子命令来正确导入环境?

时间:2009-07-29 14:52:10

标签: perl environment

在从子命令导入环境时,我想将从bash脚本导出的所有环境变量添加到散列中。当program运行时,它将设置一些变量并导出它们。我想将这些变量保存在Perl脚本中以供日后使用。但是我不想采用子命令中定义的bash函数。目前,我有一个块:

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

有更好的方法吗?我不确定匹配initial()是否安全。处理环境变量换行符的加分点,我现在只是闭上眼睛。

3 个答案:

答案 0 :(得分:5)

你想要的是:Shell-EnvImporter

一个例子:

  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: $@";

答案 1 :(得分:1)

我假设program执行后的环境变量与传递给它的环境不同(您可以在%ENV中找到它,如jeje's answer中所述。

我对bash没有任何了解,所以我只想解决有关解析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 :(得分:0)

这对于获取所有环境变量应该没问题。

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

如果你想从一个干净的平板开始,这可能会更好。

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

env -i让它的子命令从一个干净的平板开始。

它使用-c参数和要运行的命令调用bash。我们需要这样做,因为否则第二个env将无法从程序中获取环境变量。