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

发布于 2024-08-13 18:43:47 字数 1070 浏览 2 评论 0原文

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

我正在尝试修改 demarc (一个简单的网络监控工具)以对简单的脚本进行系统调用。脚本本身不执行任何操作,我只是尝试进行“概念验证”,因为我不断收到内部服务器错误。脚本的权限已设置为 777。当我注释 system() 调用时,一切都很好。所以这让我怀疑是 system() 调用发生了错误。我也尝试过 exec(),但这也不起作用。该错误不可能出现在脚本本身中,因为其中只有一个回显“测试”。

我是否错过了任何权限或者是否有其他方法可以实现此目的?任何建议将不胜感激。

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";

错误日志: [2009 年 11 月 30 日星期一 14:58:22 2009] [错误] [客户端 127.0.0.1] 脚本标头过早结束: demarc,引荐来源:http://localhost/dm/demarc?td=show_events&limit=60&sid=35

I'm sure someone could answer this very quickly, but I'm just new to perl...

I'm trying to modify demarc (a simple network monitoring tool) to do a system call to a simple script. The script itself does nothing, I'm just trying to do a 'proof-of-concept' because I keep getting an internal server error. Permissions to the script have been set to 777. When I comment the system() call, everything's fine. So that makes me suspect that it's the system() call where the error's happening. I've also tried exec(), but that didn't work also. The error could not be in the script itself since there's only an echo "test" in it.

Have I missed any permissions or is there some other way of making this work? Any advise would be appreciated.

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

This is called somewhere in file like this:

} 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";

Error log:
[Mon Nov 30 14:58:22 2009] [error] [client 127.0.0.1] Premature end of script headers: demarc, referer: http://localhost/dm/demarc?td=show_events&limit=60&sid=35

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

不打扰别人 2024-08-20 18:43:47

“脚本头提前结束”本身并不是一个非常有用的错误消息。它可能是由多种原因引起的,例如:

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

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

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

"Premature end of script headers" is not a terribly useful error message on its own. It could be caused by any of a number of things, such as:

  • not being executable (permissions problem)
  • failing compilation (syntax error, dependency problem, etc.)
  • terminating prematurely during regular execution
  • producing something other than proper HTTP headers as your script's first output

However, in this case, if we are to take your example script literally (print "TEST"), and you output this before your HTTP headers, then you are not producing HTTP headers first, so it's the last one. The web server expects headers, not "TEST."

If that's not the case, we need to see more of the context of your code to know what might have happened. Could be a permissions problem executing test.pl, for example.

晚雾 2024-08-20 18:43:47

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

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

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

One way to find the cause of the premature-thing is to make the errors go to the browser. You just have to send the content-type header early in the application, for example like this, somewhere at the top of your code:

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

Now you should be able to see the error in the browser.

牵强ㄟ 2024-08-20 18:43:47

您可能需要 system,而不是 exec

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

请参阅 exec 的文档。

You probably want system, not exec:

The exec function executes a system
command and never returns-- use system
instead of exec if you want it to
return.

See the documentation for exec.

仅一夜美梦 2024-08-20 18:43:47

好吧,我想你要做的第一件事就是检查你的网络服务器日志,它通常有一个引发内部服务器错误的原因。

Well I guess the first thing you have to do is check your web server log, it usually has a reason to throw an internal server error.

江城子 2024-08-20 18:43:47

请参阅 Perl 常见问题解答列表中的 500 服务器错误

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

See 500 Server Error in the Perl FAQ list.

You have made sure the script runs from the command line, right?

空城之時有危險 2024-08-20 18:43:47

抱怨的不是 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;

一旦有效,再尝试其他方法。

It's not the Perl CGI which complains, but Apache. Apache says your CGI script is not outputting the required headers so that's the first thing you need to achieve.

I always try CGI with a printenv script first, e.g.

#!/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;

Once that works, try something else.

爱的十字路口 2024-08-20 18:43:47

听起来您想捕获 test.pl 的输出。使用 systemexec 将无法实现这一点(并且使用 exec,您的主脚本在 test.txt 时将不再运行。 pl 运行)。

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

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

It sounds like you want to capture the output from test.pl. Using system or exec will not achieve that (and with exec, your main script will no longer be running by the time test.pl is run).

Instead, you could use backticks:

my $message = `$base_path/test.pl`;
征﹌骨岁月お 2024-08-20 18:43:47

最好尝试一下你想要做的事情的更简单的版本。

试试这个:

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

    <前><代码>#!/bin/perl
    使用“说”功能;
    使用严格;
    使用警告;
    使用数据::转储器;
    使用英文 qw<$OS_ERROR>;

    我的 $rc = system( "$base_path/test2.pl" );
    说“\$rc=$rc”;
    说$OS_ERROR;

现在,

  1. 如果$rc0。然后就可以以这种方式执行脚本了。否则,$OS_ERROR 应该告诉您。
  2. 如果这一切都有效,那么您可以尝试执行原始脚本,看看是否也有效。
  3. 如果有效,那么它可能是程序被调用时的状态。

但是,正如其他人所指出的,除非您已经完成了脚本的运行,否则从脚本执行 exec 并不是您想要做的事情,即使它是一个程序。这只会将程序加载到脚本使用的空间上。

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

It's best that you try a simpler version of what you're trying to do.

Try this:

  • Create something like test2.pl which does something simpler.
  • Run a simplified script.

    #!/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;
    

Now,

  1. If $rc is 0. Then it worked to execute the script that way. Otherwise, $OS_ERROR should tell you.
  2. If this all works, then you could try to execute the original script and see if that works as well.
  3. If that works, then it could be the state of the program at the time it is called.

But, as other people have noted, unless you're all done running the script, exec-ing from the script is not what you want to do, even if it were a program. That would just load the program over the space used by the script.

Using the qx or backticks (`) will allow the command line to be interpreted by the shell which will handle the shebangs (#!) in the perl script and return the output of the script.

岁月如刀 2024-08-20 18:43:47

[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"; <- 这行非常重要

Grettings

[client 127.0.0.1] Premature end of script headers:

you need to declare in your pl file (in case that you want to run in the browser) the content type header. Here is an example:

#!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>";

###

check the line it says: print "Content-type: text/html\n\n"; <- this line is very important

Grettings

☆獨立☆ 2024-08-20 18:43:47

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

my @array = qx(ls -1);

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

I've always been a fan of using qx for my system calls:

my @array = qx(ls -1);

system returns a string which then needs to be parsed, by qx returns an array, and if you know line 4 has the info you need, you can just go there and grab it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文