Почему мой Perl CGI жалуется на «преждевременный конец заголовков скриптов»? - PullRequest
5 голосов
/ 30 ноября 2009

Я уверен, что кто-то может ответить на этот вопрос очень быстро, но я просто новичок в Perl ...

Я пытаюсь изменить demarc (простой инструмент сетевого мониторинга), чтобы сделать системный вызов простого скрипта. Сценарий сам по себе ничего не делает, я просто пытаюсь сделать «проверку концепции», потому что я продолжаю получать внутреннюю ошибку сервера. Права доступа к сценарию установлены на 777. Когда я комментирую вызов 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";

Журнал ошибок: [Пн Ноя 30 14:58:22 2009] [error] [client 127.0.0.1] Преждевременный конец заголовков скриптов: demarc, реферер: http://localhost/dm/demarc?td=show_events&limit=60&sid=35

Ответы [ 10 ]

8 голосов
/ 30 ноября 2009

«Преждевременное завершение заголовков скрипта» само по себе не является очень полезным сообщением об ошибке. Это может быть вызвано несколькими причинами, такими как:

  • не исполняемый (проблема с правами доступа)
  • сбой компиляции (синтаксическая ошибка, проблема с зависимостями и т. Д.)
  • преждевременно завершается при обычном выполнении
  • производит что-то отличное от правильных заголовков HTTP в качестве первого вывода вашего скрипта

Однако, в этом случае, если мы возьмем ваш пример сценария буквально (print "TEST"), и вы выведете его перед заголовками HTTP, тогда вы не будете сначала создавать заголовки HTTP, поэтому это последний. Веб-сервер ожидает заголовки, а не «ТЕСТ».

Если это не так, нам нужно увидеть больше контекста вашего кода, чтобы узнать, что могло произойти. Может быть проблема с разрешениями при выполнении test.pl, например.

2 голосов
/ 01 декабря 2009

Один из способов найти причину преждевременности - заставить ошибки перейти в браузер. Вам просто нужно отправить заголовок типа контента в самом начале приложения, например, так, где-то вверху кода:

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

Теперь вы должны увидеть ошибку в браузере.

2 голосов
/ 30 ноября 2009

Ну, я думаю, первое, что вам нужно сделать, это проверить журнал вашего веб-сервера, обычно у него есть причина, чтобы вызвать внутреннюю ошибку сервера.

2 голосов
/ 30 ноября 2009

Вы, вероятно, хотите system, а не exec:

Функция exec выполняет систему команда и никогда не возвращается - использовать систему вместо exec, если вы хотите вернуться.

См. Документацию для exec .

1 голос
/ 01 декабря 2009

Жалуется не Perl CGI, а Apache. Apache говорит, что ваш CGI-скрипт не выводит требуемые заголовки, поэтому это первое, что вам нужно сделать.

Я всегда сначала пробую CGI со скриптом printenv, например,

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

Как только это сработает, попробуйте что-нибудь другое.

1 голос
/ 30 ноября 2009

См. 500 Ошибка сервера в списке часто задаваемых вопросов по Perl.

Вы убедились, что скрипт запускается из командной строки, верно?

0 голосов
/ 29 декабря 2013

[клиент 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"; <- эта строка очень важна </p>

Grettings

0 голосов
/ 30 ноября 2009

Я всегда был поклонником использования qx для моих системных вызовов:

my @array = qx(ls -1);

система возвращает строку, которую затем необходимо проанализировать, qx возвращает массив, и если вы знаете, что в строке 4 есть нужная вам информация, вы можете просто пойти туда и взять ее.

0 голосов
/ 30 ноября 2009

Лучше всего попробовать более простую версию того, что вы пытаетесь сделать.

Попробуйте это:

  • Создайте что-то вроде 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. Если $rc равно 0. Тогда это работало, чтобы выполнить сценарий таким образом. В противном случае $OS_ERROR должен сказать вам.
  2. Если все это работает, то вы можете попробовать выполнить оригинальный скрипт и посмотреть, работает ли оно также.
  3. Если это работает, то это может быть состояние программы во время ее вызова.

Но, как отметили другие люди, если вы все не запустили сценарий, exec - извлечение из сценария не то, что вы хотите сделать, даже если это была программа. Это просто загрузит программу в пространство, используемое скриптом.

Использование qx или обратных кавычек (`) позволит интерпретировать командную строку оболочкой, которая будет обрабатывать shebangs (#!) в сценарии perl и возвращать выходные данные скрипт.

0 голосов
/ 30 ноября 2009

Звучит так, как будто вы хотите захватить вывод из test.pl. Использование system или exec не приведет к этому (а при использовании exec ваш основной сценарий больше не будет работать ко времени выполнения test.pl).

Вместо этого вы можете использовать обратные пометки:

my $message = `$base_path/test.pl`;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...