这段 Perl 代码是做什么的?

3
在cPanel中,他们告诉你将这段代码插入到Perl文件的开头。我不确定它的作用是什么。我尝试了有和没有这段代码在文件开头的代码,似乎都能正常工作。但我只是以自己的身份测试过,还没有使用cron来运行代码进行测试。通过“测试”,我指的是使用print语句、数据库连接和返回、子程序、变量等等...
BEGIN 
{
    my $base_module_dir = (-d '/home/root/perl' ? '/home/root/perl' : ( getpwuid($>) )[7] . '/perl/');
    unshift @INC, map { $base_module_dir . $_ } @INC;
}
3个回答

10

这个模块旨在设置您的模块搜索路径。具体来说,它将用户本地perl/目录设置为默认位置(第一个被检查的位置)。它不仅会添加该目录,还会将其作为@INC的新根目录。对于@INC中的每个条目都会这样做。在像使用CPanel的受限访问环境中,这可以确保您的脚本(一般是cgi)使用您的模块而不是其他任何模块。

BEGIN表示它发生在块外的任何代码之前。

第一行确定是否存在/home/root/perl目录并且是否是一个目录。如果两者都为真,则将其分配给$base_module_dir,否则将<user home>/perl/分配给该变量。请记住,在Perl中,如果函数调用返回列表,则可以直接对其进行索引。

它使用getpwuid($>)查找用户的主目录。getpwuid()获取给定用户(通常从Unix系统上的passwd获取)的用户帐户信息,并将其作为列表返回。 $>是脚本的有效用户ID。索引为7的原因是该列表中主目录的位置(如果我没记错的话,它是passwd中的第8个字段)。

然后,它将@INC中的所有条目前缀添加为$base_module_dir,并将这些修改后的条目插入@INC的开头。因此,它不仅将$base_module_dir作为目录添加,还将其作为@INC中所有条目的新根添加。这就是为什么它使用map而不仅仅添加一个单个条目的原因。


啊,好的。我已经删除了我的回复,因为我错过了地图的效果。感谢您指出这一点。给HerbN加1。 - T.Rob
这段代码是什么意思? "( getpwuid($>) )[7]" 我不明白 $> 和数组引用 (?) 的 [7] 是什么。 - CheeseConQueso

8
也许更易读一些:

可能更容易阅读:

# The BEGIN block is explained in perldoc perlmod

BEGIN {
    # Prefix all dirs already in the include path, with root's perl path if it exists, or the
    # current user's perl path if not and make perl look for modules in those paths first:
    # Example: 
    #     "/usr/lib/perl" => "/home/root/perl/usr/lib/perl, /usr/lib/perl"

    my $root_user_perl_dir = '/home/root/perl';

    # Fetch user home dir in a non-intuitive way:
    # my $user_perl_dir = ( getpwuid($>) )[7] . '/perl/');

    # Fetch user home dir slightly more intuitive:
    my $current_userid        = $>; # EFFECTIVE_USER_ID see perldoc perlvar
    # See perldoc perlfunc / perldoc -f getpwuid
    my ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire) 
        = getpwuid($current_userid); 
    my $current_user_home_dir = $dir; 
    my $user_perl_dir         = $current_user_home_dir . '/perl/';

    my $base_module_dir = '';

    if (-d $root_user_perl_dir ) { 
        # Use this if the path exists
        $base_module_dir = $root_user_perl_dir;
    }
    else { 
        # or fallback to current user's path
        $base_module_dir = $user_perl_dir;
    }

    # Generate the new paths
    my @prefixed_INC = map { $base_module_dir . $_ } @INC;

    # Add the generated paths in front of the existing ones.
    @INC = (@prefixed_INC, @INC); 
}

这段代码是干嘛用的?“( getpwuid($>) )[7]”,我不理解$>以及数组引用(?)中的[7]。 - CheeseConQueso
Dummy00001:什么部分?它可以为人类编写吗? :-) - nicomen

3
这段代码设置Perl优先使用/home/root/perl(如果该目录存在且为目录)或~/perl中的模块。它基本上将Perl通常使用的每个路径都基于所选目录。这样,用户可以拥有系统模块的调试或错误修复版本,并使Perl优先使用它。
它在BEGIN块中执行此操作,因为这是确保可以运行一系列逻辑以修改@INC以影响use语句行为的唯一方法。

它不是在目录前添加,而是将该目录添加到 @INC 的所有成员名称之前,并将该较大列表添加到 @INC 的前面,因此使用了 map 函数。 - HerbN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接