从“使用”命令中删除用户名

时间:2019-11-14 08:12:49

标签: perl

我所有的Perl文件都以/ home / UserName / lib use命令开头。有没有办法从我所有的.pl文件中删除硬编码的 UserName ?我想简化针对不同用户和不同域的网站复制。这是一个Perl模板网站,该网站从URL中获取cfg = UserName参数,并根据特定的用户格式呈现该网站。但是所有用户的lib文件都一样!

您可以改用类似的方法吗?使用lib'./lib'; 抱歉,我对perl编程的了解非常有限。

示例:

use lib '/home/UserName/lib';
use RT::RealTime;
use RT::Site;
.... 

任何能提供帮助的人都会感激不尽。

3 个答案:

答案 0 :(得分:8)

如果我正确理解了您的要求,一种方法是

use warnings;
use strict;

my $user_name;
BEGIN { $user_name = $ENV{USER} }

use lib "/home/$user_name/lib";

# use packages from that path...

这将设置运行脚本的用户的用户名。

更好的是,在这种特殊情况下实际上并不需要使用BEGIN,因为%ENV是解释器设置的全局变量,因此您可以可以简单地说

use lib "/home/$ENV{USER}/lib";

use lib "$ENV{HOME}/lib"

但是,这不能满足许多​​其他相关需求,这就是为什么我(首先)展示了一种方法来解决BEGIN块中编译时没有交给我们的事情的原因。

在这种情况下,围绕BEGIN的小舞如下。 use在编译时运行,因此$user_name必须已经可用;因此,我们将其设置在BEGIN块中,该块必须在使用变量的use语句之前 出现。但是,我们需要在块之外声明变量(并且my是编译时语句)。

然后可以将所有内容包装在另一个块中,将代码从my $user_nameuser lib...之后,以限定$user_name变量的范围,以便在其余变量中看不到该变量。文件。

另一种选择似乎是将这些软件包简单地移动到用户无关的位置,然后在该use lib语句中不需要用户名...?

答案 1 :(得分:3)

  

您可以改用类似的方法吗? use lib './lib';

差不多,但不太完全。

use lib './lib';的问题在于,当用户运行脚本时,它将查找用户当前工作目录下的lib/目录。这意味着该程序仅在用户运行时位于正确的目录中时才能正常运行。如果它们恰好位于攻击者创建了恶意lib/子目录的目录中,该目录包含与您的代码使用的模块名称匹配的模块文件,则还会造成潜在的安全问题。

相反,Perl惯用的方法是:

use FindBin '$RealBin';
use lib "$RealBin/lib";

使用FindBin时,它将找到包含您正在运行的Perl程序的文件,并将$RealBin设置为该文件所在的目录路径。然后use lib将使用该路径下的lib/目录,而不管程序从哪个目录启动。

答案 2 :(得分:2)

要包含相对于当前文件的目录中的库,请使用lib::relative

# in file /home/user/project/foo.pl
use lib::relative 'lib'; # includes /home/user/project/lib
use lib::relative '../lib'; # includes /home/user/lib

这会将其转换为绝对路径,在@INC中具有相对路径是一个坏主意,因为它依赖于当前的工作目录,该目录可以是任何东西,并且可以随时更改。

lib :: relative也可以使用已记录的核心模块轻松复制。