我有一个非常棘手的诊断perl问题,这严重妨碍了我维护perl / cgi网站的能力。它通常发生在编辑脚本时 - 在更改后我得到错误500,然后在我恢复之后它再也无法工作,除非我删除文件并从头开始,但是我目前有一个状态,它可以通过以下方式再现简单的两个脚本,显示这个bug有多疯狂:
file1.pl
#! /usr/bin/perl
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
print "content-type: text/html\n\nIt works";
file2.pl
#! /usr/bin/perl
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
print "content-type: text/html\n\nIt works";
(即......他们是完全相同的)
server.com/cgi-bin/file1.pl正常工作
server.com/cgi-bin/file2.pl导致错误500
两个文件都具有相同的大小和md5哈希值。 两者都具有相同的权限(755)和相同的所有者和组。 两者都在正确的文件夹中(托管提供的cgi-bin)。 两者都以文本模式上传。 两者都与当地的perl口译人员合作。
如果我重命名file1 - > file3,file2 - > file1和file3-> file2,(即交换两个文件),现在file2.pl工作,file1.pl没有。所以我的猜测是一些状态附加到文件本身。
如果我编辑filezilla中的文件并重新上传(例如在分号后添加一些空格),重新上传的文件会出现相同的行为。
我的错误500页面设置为使用元刷新进行自动重试(如果出现内存错误等),并且在无数次刷新后它不会消失。首先访问哪些是不重要的。
我无法访问此主机上的http error_log,因此不知道失败的原因。如果没有“使用错误消息到浏览器”诊断线,也会发生错误。
任何人都可以告诉我这可能是什么并帮助我解决它吗?
答案 0 :(得分:2)
您描述的内容可能是由您的托管服务提供商方面的某些问题(某些错误的缓存,透明代理或任何其他魔法)引起的,或者 - 我认为它仍然是由错误的文件权限引起的或者换行,即使您的文件管理器报告一切都很好。
如果我正确地阅读了您的描述,那么基本上
由于您没有shell访问权限,只需将以下小脚本放到同一目录中并运行它(希望它能够运行,因为您不打算编辑它):
#!/usr/bin/perl
use strict;
use warnings;
print "Content-Type: text/plain\n\n";
opendir( my $dirh, "." );
my @files = grep { -f $_; } readdir $dirh;
closedir $dirh;
foreach my $file (@files) {
my @stat = stat $file;
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev,
$size, $atime, $mtime, $ctime, $blksize, $blocks
) = stat($file);
my $octmode = sprintf "%04o", $mode & 07777;
print "$file\tmode=$octmode\tuid=$uid\tgid=$gid\tsize=$size\t";
if ( -r $file ) {
open( my $fh, $file );
my $firstline = <$fh>;
print $firstline =~ /\r\n/ ? "crlf\n" : "lf\n";
close $fh;
} else {
print "can't read\n";
}
}
它将显示真实的权限,换行符和文件大小 - 从服务器的文件系统获取的文件,而不是FTP客户端显示的文件。
也许值得为此脚本添加MD5或SHA1哈希计算,但不确定您是否有Digest::MD5
或Digest::SHA1
。
如果您看到test1.pl
和test2.pl
的输出相同,请继续联系您的托管服务提供商的支持。
答案 1 :(得分:0)
我猜:文件不能使用相同的newline convention。
您可以使用the file
command来检查(在Unix shell中)。
答案 2 :(得分:0)
无法检查错误日志是一件非常令人头疼的事。
然而,我怀疑原因仍然很可能是行结束。我会上传一个脚本来检查你的所有文件,如下所示:
#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
use CGI qw(header);
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
use File::stat;
print header('text/plain');
my $fmt = "%-15s %4s %4s %4s %7s %4s %4s\n";
printf $fmt, qw(File mode uid gid size lf crlf);
printf $fmt, map { '-' x $_ } $fmt =~ /(\d+)/g;
opendir my $dh, '.';
while ( my $file = readdir $dh ) {
next unless -f $file;
my $stat = stat $file;
my %chars;
my $data = do { local ( @ARGV, $/ ) = $file; <> };
$chars{$1}++ while $data =~ /(\R)/g;
printf $fmt, $file, sprintf( "%04o", $stat->mode & 07777 ), $stat->uid,
$stat->gid, $stat->size, map { $_ // 0 } @chars{ "\n", "\r\n" };
}
输出:
Content-Type: text/plain; charset=ISO-8859-1
File mode uid gid size lf crlf
--------------- ---- ---- ---- ------- ---- ----
env.cgi 0775 0 0 266 25 0
le.pl 0775 501 0 696 28 0
lineendings.pl 0755 501 0 516 30 0
mywiki.pl 0755 501 0 226947 0 6666
test.cgi 0755 0 0 2071 65 0
wiki.pl 0755 0 0 219231 6494 0
对于其他测试,我建议使用system
执行每个脚本并检查错误条件(如果有)。
答案 3 :(得分:0)
我遇到了同样的问题,得到了用户BOC的帮助,如下所示: “您可能会遇到字符编码问题。有些编辑器在保存文件时会用非常接近的字符替换某些字符(例如”by“)。尝试更改编辑器(记事本++在Windows上运行良好)。 - 中银“ 我下载并使用Notepad ++而不是Notepad和Winword;它现在适合我。