为什么我的Perl CGI抱怨“过早结束脚本标题”?

时间:2009-11-30 19:22:58

标签: perl cgi

我确信有人可以很快回答这个问题,但我只是新来的...

我正在尝试修改demarc(一个简单的网络监控工具)来对简单脚本进行系统调用。脚本本身什么都不做,我只是想做一个'概念验证',因为我不断收到内部服务器错误。脚本的权限已设置为777.当我评论system()调用时,一切都很好。所以这让我怀疑它是发生错误的system()调用。我也试过exec(),但那也不行。错误不能出现在脚本本身,因为其中只有一个echo“test”。

我是否错过了任何权限,还是有其他方式使这项工作?任何建议将不胜感激。

sub generate_ticket {
   my @args = ("$base_path/test.pl");
   exec(@args);
}

这在文件中的某处称为:

} elsif ($FORM{'delete_type'}=~/generate/) {
    my $message = &generate_ticket($delete_array_ref);
    #&ack_events($delete_array_ref);
    $events_deleted = (@$delete_array_ref);
    &push_message("<FONT COLOR=red><B>Result: $message.</B></FONT>");
}

test.pl:

#!/usr/bin/perl
print "Test";

错误日志: [Mon Nov 30 14:58:22 2009] [错误] [client 127.0.0.1]脚本标题过早结束:demarc,referer:http://localhost/dm/demarc?td=show_events&limit=60&sid=35

10 个答案:

答案 0 :(得分:8)

“脚本标头的过早结束”本身并不是一个非常有用的错误消息。它可能是由许多事情引起的,例如:

  • 不可执行(权限问题)
  • 编译失败(语法错误,依赖性问题等)
  • 在常规执行期间提前终止
  • 生成除正确的HTTP标头之外的其他内容作为脚本的第一个输出

但是,在这种情况下,如果我们要按字面意思(print "TEST")获取示例脚本,并在HTTP标头之前输出,那么您不会首先生成HTTP标头,因此它是最后一个。 Web服务器需要标题,而不是“TEST。”

如果情况并非如此,我们需要查看更多代码的上下文,以了解可能发生的情况。可能是执行test.pl的权限问题,例如。

答案 1 :(得分:2)

您可能想要system,而不是exec

  

exec函数执行系统   命令,永不返回 - 使用系统   如果你想要它而不是exec   返回。

请参阅exec的文档。

答案 2 :(得分:2)

嗯,我想你要做的第一件事就是检查你的网络服务器日志,它通常有理由抛出内部服务器错误。

答案 3 :(得分:2)

找到过早事物原因的一种方法是将错误发送到浏览器。您只需在应用程序的早期发送内容类型标头,例如,在代码顶部的某处:

BEGIN {
    print "Content-type: text/plain\n\n";
}

现在您应该能够在浏览器中看到错误。

答案 4 :(得分:1)

请参阅Perl常见问题列表中的500 Server Error

您已确保脚本从命令行运行,对吗?

答案 5 :(得分:1)

这不是抱怨的Perl CGI,而是Apache。 Apache说你的CGI脚本没有输出所需的标题,所以这是你需要做的第一件事。

我总是首先使用printenv脚本尝试CGI,例如

#!/usr/bin/env perl

use warnings;
use strict;

print "Content-type: text/plain\r\n\r\n";
print "$_ => $ENV{$_}\r\n" for sort keys %ENV;

一旦有效,请尝试别的。

答案 6 :(得分:0)

听起来你想要捕获test.pl的输出。使用systemexec无法实现这一目标(使用exec,您的主脚本将在test.pl运行时停止运行。

相反,你可以使用反引号:

my $message = `$base_path/test.pl`;

答案 7 :(得分:0)

最好是尝试更简单的版本。

试试这个:

  • 创建像test2.pl之类的东西,它可以做更简单的事情。
  • 运行简化脚本。

    #!/bin/perl 
    use feature 'say';
    use strict;
    use warnings;
    use Data::Dumper;
    use English qw<$OS_ERROR>;
    
    my $rc = system( "$base_path/test2.pl" );
    say "\$rc=$rc";
    say $OS_ERROR;
    

现在,

  1. 如果$rc0。然后它以这种方式执行脚本。否则,$OS_ERROR应告诉您。
  2. 如果一切正常,那么您可以尝试执行原始脚本,看看是否也能正常运行。
  3. 如果可以,那么它可能是程序调用时的状态。
  4. 但是,正如其他人已经注意到的那样,除非你们都完成了脚本的运行,否则exec - 脚本不是你想要做的,即使它是一个程序。这只会在脚本使用的空间上加载程序。

    使用qx或反引号(`)将允许shell解释命令行,它将处理perl脚本中的shebangs(#!)并返回脚本的输出。

答案 8 :(得分:0)

[client 127.0.0.1]脚本标题的提前结束:

您需要在pl文件中声明(如果您想在浏览器中运行)内容类型标题。这是一个例子:

#!c:/wamp/bin/perl/bin/perl.exe

print "Content-type: text/html\n\n";
print "<html><head><title>Test</title></head>";
print "<body>";
print "Hello";
print "</body></html>";

###

检查它说的行:print“Content-type:text / html \ n \ n”; &lt; - 这一行很重要

素不相识

答案 9 :(得分:-2)

我一直都喜欢使用qx进行系统调用:

my @array = qx(ls -1);

系统返回一个需要解析的字符串,qx返回一个数组,如果你知道第4行有你需要的信息,你可以去那里抓住它。