Непоследовательное и необъяснимое поведение в некоторых файлах perl - PullRequest
4 голосов
/ 02 января 2012

Хост - это Linux.У меня есть несколько файлов в одном каталоге.Все *.pl файлы содержат в начале следующее, отличающееся только комментариями:

#!/usr/bin/perl -w

BEGIN { chdir('/home/httpd/vhosts/mysite.com/httpdocs/newsbot'); unshift(@INC, "/home/httpd/vhosts/mysite.com/httpdocs/newsbot"); }

use Form;
use File;
use Mysite;

#Read in All Form Variables
&ReadInForm;

Файл Form.pm содержит подпрограмму ReadInForm и ничего больше.

sub ReadInForm { 
}    
1;

Странная вещь в том, что результаты вышеописанного абсолютно противоречивы.Иногда он выполняется нормально, но показывает сообщение «Внутренняя ошибка сервера» в конце скрипта и помещает в файл error_log следующее:

Аргумент "" не является числовым в записи подпрограммыв /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi/ModPerl/RegistryCooker.pm строка 171. \ n, реферер: http://www.mysite.com/newsbot/groupkeywords.pl

В другое время,он не выполняется и выводит в браузер следующее:

Неопределенная подпрограмма и ModPerl :: ROOT :: ModPerl :: Registry :: home_httpd_vhosts_mysite_2ecom_httpdocs_newsbot_groupkeywords_2epl :: ReadInForm at at home / ReadInFdts v home / ReadInFdts at homemysite.com/httpdocs/newsbot/groupkeywords.pl строка 11.

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

Странно то, что он несовместим.Я могу получить один вывод из файла, обновить через несколько минут, а затем получить другой.У меня даже есть несколько сообщений «Внутренняя ошибка сервера» и заголовок ответа 500 без какого-либо фактического содержания.Комментирование строки &ReadInForm; решает проблему каждый раз, поэтому я сузил ее до этого, однако не имеет значения, что я вставил в Form.pm.Я даже могу поставить пустую подпрограмму (как у меня выше), и она все еще не решает проблему.

Я даже не уверен, как отладить это.Как это вообще возможно, чтобы быть непоследовательным?Компилятор perl выполняет какое-то скрытое кэширование?

Ответы [ 2 ]

5 голосов
/ 02 января 2012

Очевидно, ваш хост использует Apache mod_perl. Вы должны явно указать код для mod_perl. Кстати, ваш код пахнет perl 4 и cgi-lib.pl, винтаж 1996 года. Проще говоря, в mod_perl ваш скрипт не может работать, потому что глобальные переменные полностью запрещены и , вы не можете изменить @INC в mod_perl в любом случае. Вам лучше поставить «use strict; use warnings;» в свой скрипт и использовать надлежащие модули и функции синтаксического анализа форм CGI или mod_perl.

Однако этот стиль кода должен работать:

#!/usr/bin/perl

# I don't know what this BEGIN block is for, but I suspect it may not work or causes subtle bugs...
BEGIN { chdir('/home/httpd/vhosts/mysite.com/httpdocs/newsbot'); }


use strict;
use warnings;
use Form;
use File;
use Mysite;

#Read in All Form Variables
Form::ReadInForm();

С этим в Form.pm:

use strict;
use warnings;

package Form;

sub ReadInForm { 
}    
1;

Редактировать : если ваш код устарел и вы хотите сэкономить на капитальном ремонте, вы можете создать «основную» подпрограмму, содержащую весь код скрипта и объявления переменных, и просто вызвать его следующим образом: способ:

Старый скрипт:

#!/usr/bin/perl

# the following line will fail with "undeclared variable" under "use strict"
$a="test";
print "$a\n";

Новый скрипт:

#!/usr/bin/perl

use strict; 
use warnings;

# call the main loop enclosing everything else    
main();

sub main {
    # first declare all variables
    my $a;

    # then add there all the code:
    $a="test";
    print "$a\n";
}

Таким образом, сценарий можно «модернизировать» дешево и очень быстро.

0 голосов
/ 23 ноября 2017

Позднее, в 2017 году, мне есть что добавить в эту ветку, основываясь на моем недавнем подобном опыте. Для меня очевидно, что старый унаследованный Perl-код 1990 года должен вызывать странные ошибки при запуске под mod_perl, как ясно и кратко объяснено в (http://www.fifi.org/cgi-bin/man2html/usr/share/man/man3/mod_perl_traps.3pm.gz).. Из другой документации также очевидно, что mod_perl был создан для ускорения Perl 35-кратный серверный код из-за повторного использования потоков, но следует избегать некоторых старых методов Perl CGI, чтобы эта работа работала чисто.

Что теоретически БОЛЬШОЙ! Но не всегда ...

Мое единственное предостережение - это для сообщества энтузиастов perl_mod-гуру. При принятии решения о том, как запускать устаревший Perl, не предлагайте автоматически использовать mod_perl, и, таким образом, вынудите последующее множество неожиданных изменений кода для ничего не подозревающего человека, переносящего устаревший код Perl.

Вместо этого сначала определите, должен ли унаследованный код работать с максимальной эффективностью (в многопоточной среде с возможностью многократного использования) или подходит ли старомодный однопоточный CGI.

Как в моем случае. В 1998 году я написал замечательную небольшую онлайновую систему заказов CGI на Perl. Одна из первых в своем роде. Теперь (в 2017 году) я хотел развернуть его просто для демонстрации старого кода, который я написал (например, резюме). Он никогда не будет запущен, за исключением демонстрации.

Итак, mod_perl - это OVERKILL, но системные администраторы на моем новом хостинг-сайте настаивали на том, чтобы я установил mod_perl, который, как я понимаю, был их рекомендуемой общей привычкой, но впоследствии стало ясно, что они ничего не знают о том, что mod_perl делает с старая CGI Perl система. Но в то время я тоже. Итак, я сделал, как они просили, и только потом узнал о подводных камнях mod_perl, когда попал в них один за другим.

Если бы я просто не загрузил mod_perl, ни одна из этих ошибок не произошла бы, поскольку конфигурация сервера по умолчанию была старомодным CGI.

Предостережение Emptor.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...