Как правильно импортировать среду из запуска подкоманды в Perl? - PullRequest
2 голосов
/ 29 июля 2009

При импорте среды из подкоманды я хочу добавить все переменные среды, экспортированные из bash-скрипта, в хеш. Когда program запускается, он устанавливает некоторые переменные и экспортирует их. Я хотел бы сохранить эти переменные в скрипте Perl на потом. Однако я не хочу использовать функции bash, определенные в подкоманде. В настоящее время у меня есть блок, как:

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

Есть ли лучший способ сделать это? Я не уверен, что соответствие initial () безопасно. Бонусные баллы за обработку строк в переменных окружения, на которые я сейчас закрываю глаза.

Ответы [ 3 ]

5 голосов
/ 29 июля 2009

То, что вы хотите, есть: 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 голос
/ 29 июля 2009

Я предполагаю, что переменные окружения после выполнения program не совпадают с передаваемой ему средой (которую вы можете найти в %ENV, как объяснено в ответе jeje .

Я отнюдь не разбираюсь в 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;
0 голосов
/ 29 июля 2009

Это хорошо для получения всех переменных среды.

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

Если вы хотите начать с чистого листа, это может сработать лучше.

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

env -i запускает подкоманду с чистого листа.

Вызывает bash с аргументом -c и командами для запуска. Нам нужно это сделать, потому что в противном случае второй env не получит переменные окружения из программы.

...