使用perl cgi时错误500 - 但不是任何常见的陷阱

时间:2014-09-30 18:03:14

标签: perl cgi

我有一个非常棘手的诊断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,因此不知道失败的原因。如果没有“使用错误消息到浏览器”诊断线,也会发生错误。

任何人都可以告诉我这可能是什么并帮助我解决它吗?

4 个答案:

答案 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::MD5Digest::SHA1

如果您看到test1.pltest2.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;它现在适合我。