好的,所以-首先,我不确定您config.pl
是否真的是正确的方法-它不perl
适合初学者,因为它无法编译。不管怎样,尝试评估东西以“解析配置”通常不是一个好计划——它很容易出现令人不快的故障和安全漏洞,所以应该在需要时保留。
我会敦促您通过以下方式以不同的方式进行操作:
把它写成一个模块
像这样的东西:
package MyConfig;
# Configuration file for main script
our %config = (
username => "username",
password => "none_of_your_business",
favorite_color => "0x0000FF",
);
然后你可以在你的主脚本中:
use MyConfig; #note - the file needs to be the same name, and in @INC
并访问它:
print $MyConfig::config{username},"\n";
如果你不能把它放在现有的@INC
- 这可能有你不能的原因,FindBin
让你使用相对于你的脚本位置的路径:
use FindBin;
use lib "$FindBin::Bin";
use MyConfig;
将您的“配置”编写为已定义的可解析格式,而不是可执行代码。
YAML
YAML
对于配置文件来说非常可靠,尤其是:
use YAML::XS;
open ( my $config_file, '<', 'config.yml' ) or die $!;
my $config = Load ( do { local $/; <$config_file> });
print $config -> {username};
您的配置文件如下所示:
username: "username"
password: "password_here"
favourite_color: "green"
air_speed_of_unladen_swallow: "african_or_european?"
(YAML 还支持多维数据结构、数组等。不过你似乎不需要这些。)
JSON
JSON
based 看起来很相似,只是输入是:
{
"username": "username",
"password": "password_here",
"favourite_color": "green",
"air_speed_of_unladen_swallow": "african_or_european?"
}
你读它:
use JSON;
open ( my $config_file, '<', 'config.json' ) or die $!;
my $config = from_json ( do { local $/; <$config_file> });
使用相对路径进行配置:
您完全不必担心@INC
。您可以简单地基于相对路径使用......但更好的选择是不这样做,FindBin
而是使用 - 它可以让您指定“相对于我的脚本路径”,这更加健壮。
use FindBin;
open ( my $config_file, '<', "$FindBin::Bin/config.yml" ) or die $!;
然后你就会知道你正在阅读与你的脚本在同一目录中的那个,无论它是从哪里调用的。
具体问题:
无论如何,从谁的角度来看是“./”:Perl 二进制文件、执行的 Perl 脚本、来自用户 shell 的 CWD,还是其他?
当前工作目录通过进程向下传递。所以默认情况下用户的shell,除非perl脚本执行chdir
是否存在需要注意的安全风险?
任何时候您“评估”某些东西,就好像它是可执行代码(并且EXPR
可以是)存在安全风险。它可能并不大,因为脚本将以用户身份运行,而用户是可以篡改的人CWD
。核心风险是:
- 用户位于“不同”目录中,其他人在该目录中放置了恶意内容供他们运行。(例如,想象一下“config.pl”
rm -rf /*
在其中)。也许/tmp
他们不小心“运行”了一个“config.pl”?
- 你正在输入的东西
eval
有一个错字,并以时髦和意想不到的方式破坏了脚本。(例如,它可能会$[
以难以调试的方式重新定义和混淆程序逻辑)
- script 在特权上下文中执行任何操作。情况似乎并非如此,但请参阅前一点并想象您是
root
或其他特权用户。
这比修改@INC 并仅使用基本文件名更好还是更差?
更糟糕的海事组织。实际上只是根本不修改@INC
,并使用完整路径,或使用FindBin
. 并且不要eval
在没有必要的时候做事。