如何在 Perl 脚本之间共享 ENV 变量

Posted

技术标签:

【中文标题】如何在 Perl 脚本之间共享 ENV 变量【英文标题】:How to Share ENV Variables Among Perl Scripts 【发布时间】:2017-06-23 13:42:09 【问题描述】:

我有两个 Perl 脚本以及 GIT 钩子脚本。在那里我正在验证 GIT 工作流程。这里是脚本调用堆栈。

pre-push -> unpush-changes -> 依赖树

在 unpush-changes perl 脚本中有一个 for 循环将调用依赖树 perl 脚本。

预推

system("unpushed-changes");
  my $errorMsg = $ENV'GIT_FLOW_ERROR_MSG'// '';
  if($errorMsg eq "true")
     print "Error occured!";
   

unpush-changes.pl

  for my $i (0 .. $#uniqueEffectedProjectsList) 
      my $errorMsg = $ENV'GIT_FLOW_ERROR_MSG'// '';
      if($errorMsg ne "true")
        my $r=system("dependency-tree $uniqueEffectedProjectsList[$i]");
     else
        exit 1;
     

   

依赖树.pl

if(system("mvn clean compile  -DskipTests")==0)
     print "successfully build"; 
     return 1;
 else
      $ENV'GIT_FLOW_ERROR_MSG' = 'true';
      print "Error occured";
      return 0;
  

在我的 dependency-tree 脚本中,如果发生错误,我已经设置了 ENV 变量,这将在 unpush-changes 脚本。但它的 ENV 值为空,而不是 true。如果失败,我还尝试返回一些值并尝试验证它,但似乎它也不起作用。所以我的要求是我如何在所有脚本之间共享一个全局变量。如果有更好的方法,请告诉我。

【问题讨论】:

perldoc -q environment 现在可以使用Env::Modify @mob 我不知道那个模块。我将重新打开问题,以便您回答。然后,我们应该关闭另一个相关问题的链接。 如果您的所有system 调用都只是调用其他perl 脚本,更好的方法是将您的perl 脚本转换为函数/库并从单个perl 进程调用所有内容。在进程之间共享环境变量是多余的。 【参考方案1】:

一般来说,子进程从其父进程继承一个单独的环境副本,并且子进程所做的更改不会传播到父进程的环境。 Env::Modify 提供了解决此问题的方法,实现了 perlfaq 谈到的 "shell magic"。

典型用法:

use Env::Modify 'system',':bash';

print $ENVFOO;                   #   ""
system("export FOO=bar");
print $ENVFOO;                   #   "bar"
...
print $ENVGIT_FLOW_ERROR_MSG;    #   ""
system("unpushed-changes");
print $ENVGIT_FLOW_ERROR_MSG;    #   "true"
...

【讨论】:

【参考方案2】:

正如@mob 提到的,有两种方法可以实现这一点。Env::Modify 或作为 perl lib。所以我选择了lib 而不是Env::Modify。因为我想在每台机器上明确地运行这个脚本Env::Modify 包是否安装。

我编写了 Utils.pm,将 unpush-changesdependency-tree 功能捆绑在一起,并将其保存在 /c/lib/My/Utils.pm 下。

Utils.pm

package My::Utils;
use strict;
use warnings;

use Exporter qw(import); 
our @EXPORT_OK = qw(build deploy);

sub build 
 system("mvn clean compile  -DskipTests")
 //Do  other things


sub deploy 
 //Do  things


1;

然后我在 pre-push 挂钩中使用了之前创建的库。

预推

#!/usr/bin/perl
use strict;
use warnings;
use File::Basename qw(dirname);
use Cwd  qw(abs_path);
use lib dirname(dirname abs_path $0) . '/lib'; 
use My::Utils qw(build deploy); // or use lib '/c/lib';

build();
deploy();

不再需要担心ENV变量。Reference

【讨论】:

对于这个问题,这绝对是要走的路。

以上是关于如何在 Perl 脚本之间共享 ENV 变量的主要内容,如果未能解决你的问题,请参考以下文章