Что делает этот Perl-код? - PullRequest
3 голосов
/ 25 августа 2010

В cPanel говорят, что вы должны вставить этот код в начало файлов Perl.Я не уверен, что это делает.Я пробовал код с и без этого в начале файла, и кажется, что все работает одинаково.Я не проверял это с помощью cron, выполняющего код, но только как я сам.Под «проверкой» я подразумеваю использование строк печати, соединений с базой данных и возвратов, подпрограмм, переменных и т. Д. *

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

Ответы [ 3 ]

10 голосов
/ 25 августа 2010

Предназначен для установки пути поиска вашего модуля. В частности, он устанавливает местоположение по умолчанию (первое местоположение проверено) в локальном каталоге пользователя perl/. Он не только добавляет этот каталог, но и делает его новым корнем для @INC. Это делается для каждой записи в @ INC. В среде с ограниченным доступом, такой как среда, в которой используется CPanel, это гарантирует, что ваши скрипты (общие cgi) будут использовать ваши модули над любыми другими.

НАЧАТЬ означает, что это происходит до того, как какой-либо код не находится в блоке.

Первая строка определяет, существует ли /home/root/perl и является ли он каталогом. Если оба имеют значение true, он присваивает это $base_module_dir, в противном случае присваивает <user home>/perl/ переменной. Помните, что в perl вы можете индексировать вызов функции напрямую, если она возвращает список.

Находит домашний каталог пользователя с getpwuid($>). getpwuid() получает информацию об учетной записи пользователя для данного пользователя (обычно из passwd в системе Unix) и возвращает ее в виде списка. $> - эффективный идентификатор пользователя скрипта. Причиной индекса 7 является расположение домашнего каталога в списке (и это 8-е поле в passwd, если память служит).

Затем он добавляет ВСЕ записи в @INC с $base_module_dir и вставляет эти измененные записи в начало @INC. Так что это не просто добавление $base_module_dir в качестве каталога, но и добавление его в качестве нового корня для всех записей в @INC. Вот почему он использует map вместо простого добавления одной записи.

8 голосов
/ 25 августа 2010

Может быть, немного легче читать:

# 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); 
}
3 голосов
/ 25 августа 2010

Этот код устанавливает Perl для предпочтения модулей либо в /home/root/perl - если он существует и является каталогом - либо ~/perl при поиске модулей для загрузки. В основном он берет каждый путь, который обычно использует Perl, и размещает их в выбранном каталоге.

Вероятно, это позволяет пользователю иметь версию системного модуля для отладки или исправления ошибок, а Perl предпочитает это.

Он делает это в блоке BEGIN, потому что это единственный способ убедиться, что блок логики можно запустить для изменения @INC, чтобы повлиять на поведение use операторов.

...