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番目のフィールドです)。

次に、すべてのエントリをの前に追加@INC$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 に答える