主机是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,referer:{{ 3}}
其他时候,它不会执行,并将以下内容输出到浏览器:
Undefined subroutine& ModPerl :: ROOT :: ModPerl :: Registry :: home_httpd_vhosts_mysite_2ecom_httpdocs_newsbot_groupkeywords_2epl :: ReadInForm,在/home/httpd/vhosts/mysite.com/httpdocs/newsbot/groupkeywords.pl第11行调用。
其他时候它正常工作,没有错误。
奇怪的是它不一致。我可以从文件中获取一个输出,几分钟后刷新,然后获取另一个。我甚至有一些“内部服务器错误”消息和一个500响应标题,没有实际内容。评论&ReadInForm;
行每次都会解决问题,因此我将其缩小到了这一点,但是我在Form.pm
中放入的内容并不重要。我甚至可以设置一个空的子程序(如上所述)但它仍然无法解决问题。
我甚至不确定如何调试它。它怎么可能不一致呢? perl编译器是否在幕后缓存?
答案 0 :(得分:5)
显然你的主机正在使用Apache mod_perl。您必须为mod_perl显式编码。顺便说一句,你的代码闻起来有perl 4和cgi-lib.pl,1996年份。简单地说,在mod_perl下你的脚本无法工作,因为无论如何global variables are completely forbidden和you can't modify @INC under 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;
编辑:如果你的代码是旧的并且想要为你进行大修,你可以创建一个包含所有脚本代码和变量声明的“main”子,并简单地调用它这样:
旧脚本:
#!/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";
}
通过这种方式,脚本可以廉价而快速地“现代化”。
答案 1 :(得分:0)
在2017年的这个晚些时候,根据我最近的类似经历,我有一件事要添加到这个帖子中。对我来说很明显,旧的1990年的遗留perl代码在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 guru社区的爱好者。在决定如何运行遗留的perl时,不要自动建议使用mod_perl,从而迫使随后的一些意外的代码更改在毫无疑问的传统perl代码移植人身上。
首先确定遗留代码是否需要以最高效率运行(在大量使用的可重用线程环境下),或者老式单线程CGI是否正常。
就像我的情况一样。我在1998年写了一个很棒的CGI perl在线订购系统。这是同类产品中的第一个。现在(2017年)我想部署它只是为了演示我编写的一些旧代码(如简历项目)。除了作为演示之外,它永远不会被运行。
所以,mod_perl是OVERKILL,但我的新托管网站上的SysAdmins坚持我安装了mod_perl,我收集的是他们建议的共同习惯,但后来我很清楚他们对mod_perl做什么一无所知。旧的CGI perl系统。但当时我也没有。所以,我按照他们的要求做了,然后才知道mod_perl陷阱,因为我一个接一个地陷入了它们。
如果我没有加载mod_perl,那么这些错误都不会发生,因为服务器的默认配置是旧式的CGI。
警告Emptor。