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

发布于 2024-07-29 05:41:00 字数 396 浏览 2 评论 0原文

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

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱人如己 2024-08-05 05:41:00

你想要的就在那里: 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: $@";

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: $@";
墨落成白 2024-08-05 05:41:00

我假设 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;

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;
蝶…霜飞 2024-08-05 05:41:00

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

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 将无法从程序中获取环境变量。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文