3

In cPanel, they tell you to insert this code into the beginning of Perl files. I'm not sure what it does. I've tried code with and without this in the beginning of the file and it seems to all work the same. I haven't tested that out with cron running the code, but only as myself. By "tested it out", I mean using print lines, database connections & returns, subs, vars, etc...

BEGIN 
{
    my $base_module_dir = (-d '/home/root/perl' ? '/home/root/perl' : ( getpwuid($>) )[7] . '/perl/');
    unshift @INC, map { $base_module_dir . $_ } @INC;
}
4

3 回答 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 个字段)。

然后,它将所有条目添加到@INCwith中$base_module_dir,并将那些修改过的条目插入到@INC. 因此,它不仅仅是添加$base_module_dir为目录,而是将其添加为@INC. 这就是为什么它使用map而不是仅仅添加一个条目。

于 2010-08-25T15:29:36.057 回答
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); 
}
于 2010-08-25T15:40:21.497 回答
3

这段代码将 Perl 设置为首选模块/home/root/perl——如果它存在并且是一个目录——或者~/perl在寻找要加载的模块时。它基本上采用 Perl 通常使用的每条路径,并将它们基于选择的目录中。

很可能,这允许用户拥有系统模块的调试或错误修复版本,而 Perl 更喜欢它。

它在 BEGIN 块中执行此操作,因为它是确保可以运行逻辑块以修改@INC以影响use语句行为的唯一方法。

于 2010-08-25T15:27:07.523 回答