我有一堆运行工具流的脚本。就像 Makefile 一样,但在 Perl 中。
作为这些流程的一部分,Perl 脚本设置了环境变量,而且要知道它们何时发生并不总是那么容易,因此很难重现流程的各个阶段。
有没有办法挂钩 %ENV 以便我可以在环境变化时注册回调?
我可以绑定它吗?%ENV 已经表现得像平局一样。
跟进:是的。你只要把它绑起来。
我有一堆运行工具流的脚本。就像 Makefile 一样,但在 Perl 中。
作为这些流程的一部分,Perl 脚本设置了环境变量,而且要知道它们何时发生并不总是那么容易,因此很难重现流程的各个阶段。
有没有办法挂钩 %ENV 以便我可以在环境变化时注册回调?
我可以绑定它吗?%ENV 已经表现得像平局一样。
跟进:是的。你只要把它绑起来。
哦。我刚刚被我的屁股吓坏了。无论如何,据说存在一个监视器包,可以让您通过 tie 来监视对现有变量的更改。这听起来像是一个有趣的问题,所以当我开始深入研究 The Blue Camel 中的“领带”文档时,没有定义现有变量会发生什么(即 - 引用是否保存在某处?)。所以,我用谷歌搜索“perl tie”现有变量“”。不幸的是,我发现的链接在社会上是不可接受的(盗版材料),所以我几乎不存在了,声誉明智。
不过,祝你好运。
无论如何,只是为了澄清一下,它在“高级 Perl 编程”的第 9 章,即“Tie”一章中。确保您从信誉良好的网站购买副本 :-)
这是可行的。我认为执行以下操作可能会降低性能,并且我确定我没有涵盖所有可能的情况,但这绝对可以帮助您入门。
use strict;
use warnings;
tie %ENV, 'change_noticer', %ENV or die $!;
$ENV{PATH} .= ":test";
print $ENV{PATH}, "\n";
delete $ENV{PATH};
package change_noticer;
use strict;
use warnings;
use Carp;
use Tie::Hash;
use base 'Tie::StdHash';
sub DELETE {
my $this = shift;
carp "deleting \$ENV{$_[0]}";
$this->SUPER::DELETE(@_);
}
sub STORE {
my $this = shift;
carp "altering \$ENV{$_[0]}";
$this->SUPER::STORE(@_);
}
sub TIEHASH {
my $class = shift;
my $this = bless {}, $class;
while( my ($k,$v) = splice @_, 0, 2 ) {
$this->{$k} = $v;
}
return $this;
}
Variable::Magic似乎有效,但与绑定哈希不同,它似乎没有为您提供价值。
use 5.010;
use Carp qw<carp>;
use Variable::Magic qw<cast wizard>;
my $magic_hash = wizard store => sub {
carp "Hey! They're trying to set $_[-1]!";
};
cast %ENV, $magic_hash;
$ENV{HOME} = '~evilhacker';
如果我后来掏出,它似乎正确设置了环境变量,所以我不只是 clobber %ENV
:
say `echo HOME=\$HOME`;
say `echo HOME=%HOME%`;
我唯一能想到的是创建一个名为的绑定变量%ENVIRONMENT
,它充当%ENV
您可以挂钩的接口。然后使用确保您始终使用%ENVIRONMENT
而不是%ENV
.
另一件事要尝试,在字里行间阅读:不是为要运行的任务调用“system(...)”,而是实现一个“my_system(...)”,在调用外部任务之前打印出环境,这样您可以使用命令行中的“env ...”命令重新创建其中一项任务
# show the environment in which an external command runs:
sub my_system
{
print map { $_ . "='" . $ENV{ $_ } . "'\n" } keys( %ENV);
print "'" . join( "' '", @_) . "'\n";
return system( @_);
}