如何在 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 变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在Powershell中的脚本之间共享变量?

如何在 bash shell 脚本中的 perl 命令调用中使用 shell 变量?

如何在 SQL 脚本中使用 Perl 变量(使用反引号)

如何在 npm 脚本中使用 .env 变量

如何在 Makefile 规则中将 env 变量传递给 shell 脚本

将环境变量设置为从 perl 脚本执行的 shell