2

我正在编写一个perl脚本 ( myscript.pl),我想按以下顺序从各个模块加载一些环境变量:

  • 默认设置在defaultSettings.pm同一目录中myscript.pl
  • (可选)userSettings.pm用户可以选择的其他地方的用户设置
  • (可选)localSettings.pm当前工作目录中的本地设置

我已经解决了我的第一个和最后一个项目符号,但没有成功解决第二个项目。

myscript.pl

#!/usr/bin/perl 

use strict;
use warnings;
use FindBin;            
use lib $FindBin::Bin;

# defaultSettings always present in same directory as myscript.pl
use defaultSettings;   

# localSettings sometimes present (in current working directory)
eval
{
    require localSettings;
      localSettings->import();
    };

print "Some variable is: ",$someVariable;
exit 

defaultSettings.pm

package defaultSettings;

use strict;
use warnings;
use Exporter;

use vars qw($VERSION @ISA @EXPORT);

$VERSION     = 1.00;
@ISA         = qw(Exporter);
@EXPORT      = qw($someVariable
                  );

our $someVariable="default settings";
1;

localSettings.pm

package localSettings;

use strict;
use warnings;
use Exporter;

use vars qw($VERSION @ISA @EXPORT);

$VERSION     = 1.00;
@ISA         = qw(Exporter);
@EXPORT      = qw($someVariable
                  );

our $someVariable="local settings";
1;

我知道我可以使用

use lib "/home/foo/bar/";
use userSettings;

myscript.pl,但我想避免让用户编辑myscript.pl- 主要希望/目标是让用户编辑 myscript.pl.

我对完成相同想法的其他工作流程持开放态度:)

4

2 回答 2

3

不要使用 Perl 模块来存储配置数据。这不是它们的用途,而且正如您所见,它们并不真正适合此目的。还有一个潜在的安全风险是模块包含可执行的 Perl,它可以对你的系统做几乎任何事情。数据最好存储在不可执行的文件中。

相反,可以使用 JSON 数据文件之类的东西,这些文件可以放在磁盘卷上的任何位置并直接读入 Perl 数据结构。

您的主要问题似乎是如何定义第三组配置数据的位置,对我来说最明显的选项是应该在其他两组之一中指定它 - 可能是存储在当前工作目录中的那一组。

于 2013-03-18T03:13:40.377 回答
0

想到的两种方法:

  • use lib "$ENV{HOME}/bar";如果您关心的只是不要求用户输入其主目录的路径,但您可以假设该目录中的特定路径。
  • use lib $ENV{MYSCRIPT_CONFIG};如果您愿意要求用户设置该环境变量(尽管如果根本没有设置,您至少会收到警告,所以这并不理想;您可以改为创建一个BEGIN块来检查它是否已设置然后打开-编码use lib) 的效果。

但是,我会提出一个更基本的建议:我认为您正在使用use并且require当您真正需要do. 与其将所有这些随机路径添加到全局模块搜索路径(也将用于您加载的每个其他模块),不如考虑以下策略:

if ($ENV{HOME} && -f "$ENV{HOME}/bar/localSettings.pm") {
    my $file = "$ENV{HOME}/bar/localSettings.pm";
    my $status = do $file;
    die "couldn't parse file $file: $@" if $@;
    die "couldn't load $file: $!" unless defined $status;
    die "couldn't load $file" unless $status;
}

的缺点do是更冗长的错误管理。优点是您不必在模块路径中添加东西,您不必为文件命名,甚至不必为三种类型的设置文件按顺序使用单独的名称避免%INC处理阻止加载所有配置。

(另一个答案也有一个好点,即您应该始终三思而后行将 Perl 模块用于配置数据,但有时这是一个非常好的主意。一种是用户配置可以包含编写的完整回调函数在 Perl 中。我有几个软件包就是这种情况。)

于 2013-03-18T03:17:36.283 回答