Ошибка Apache при попытке запустить скрипт Perl [дубликат]

, если кадр Data выглядит так:

group         name      count
fruit         apple     90
fruit         banana    150
fruit         orange    130
vegetable     broccoli  80
vegetable     kale      70
vegetable     lettuce   125

и OUTPUT могут быть как

   group    name  count
0  fruit   apple     90
1  fruit  banana    150
2  fruit  orange    130

, если вы используете логический оператор np.logical_not

df[np.logical_not(df['group'] == 'vegetable')]

подробнее о

https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.logic.html

другие логические операторы

  1. logical_and (x1, x2, / [, out, where, ...]) Вычислить значение истинности x1 и x2 по элементам.
  2. logical_or (x1, x2, / [, out, where, casting, ...]) Вычислить значение истинности x1 OR x2 по элементам.
  3. logical_not (x, / [, out, where, casting, ...]) Вычислить значение истины NOT x по элементам.
  4. logical_xor (x1, x2, / [, out, where, ..]) Вычислить значение истины x1 XOR x2, по элементам.

96
задан 2 revs 29 January 2010 в 21:53
поделиться

8 ответов

120
ответ дан 14 revs, 7 users 78% 20 August 2018 в 20:07
поделиться

Вы можете запустить perl cgi-script в терминале, используя следующую команду

 $ perl filename.cgi

. Он интерпретирует код и предоставляет результат с кодом HTML. Он сообщит об ошибке, если таковой имеется.

0
ответ дан 2 revs, 2 users 83% 20 August 2018 в 20:07
поделиться
  • 1
    Извините, команда $ perl -c filename.cgi проверяет синтаксис кода и сообщает об ошибке, если таковая имеется. Он не будет предоставлять html-код cgi. – D.Karthikeyan 6 April 2016 в 04:07
  • 2
    Вызов perl -c filename будет действительно проверять только синтаксис. Но perl filename выводит вывод HTML. Это не гарантирует, что не будет ошибки 500 CGI, но это хороший первый тест. – Nagev 18 May 2018 в 14:46

Я думаю, что CGI :: Debug стоит упомянуть.

10
ответ дан 2 revs, 2 users 86% 20 August 2018 в 20:07
поделиться
  • 1
    Это сообщество wiki, поэтому wiki прочь :) – brian d foy 29 January 2010 в 21:52
  • 2
    К сожалению, я могу только отредактировать вопрос, а не ответы. – Mikael S 29 January 2010 в 22:31

Вероятно, стоит также упомянуть, что Perl всегда расскажет вам, в какой строке возникает ошибка при выполнении сценария Perl из командной строки. (Например, сеанс SSH)

Я обычно делаю это, если все остальное не работает. Я буду использовать SSH на сервере и вручную выполнить скрипт Perl. Например:

% perl myscript.cgi 

Если возникла проблема, Perl расскажет вам об этом. Этот метод отладки устраняет любые проблемы с разрешением файла или проблемы с веб-браузером или веб-сервером.

1
ответ дан 2 revs, 2 users 93% 20 August 2018 в 20:07
поделиться
  • 1
    Perl не всегда указывает номер строки, где возникает ошибка. Он сообщает вам номер строки, где он понимает, что что-то не так. Вероятно, ошибка уже произошла. – brian d foy 5 February 2014 в 17:10

Интересно, почему никто не упомянул вариант PERLDB_OPTS, названный RemotePort; хотя, по общему признанию, в Интернете мало рабочих примеров (RemotePort даже не упоминается в perldebug ) - и для меня было довольно проблематично придумать это, но здесь оно (это пример Linux).

Чтобы сделать правильный пример, сначала мне понадобилось что-то, что могло бы сделать очень простое моделирование веб-сервера CGI, желательно через одну командную строку. После нахождения Простой веб-сервер командной строки для запуска cgis. (perlmonks.org) , я нашел для этого теста IO :: All - A Tiny Web Server .

Здесь я буду работать в каталог /tmp; сценарий CGI будет /tmp/test.pl (см. ниже). Обратите внимание, что сервер IO::All будет обслуживать только исполняемые файлы в том же каталоге, что и CGI, поэтому здесь требуется chmod +x test.pl. Итак, чтобы выполнить обычный тестовый прогон CGI, я меняю каталог на /tmp в терминале и запускаю там один веб-сервер:

$ cd /tmp
$ perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'

Команда webserver будет блокироваться в терминале, и в противном случае запустит веб-сервер локально (на 127.0.0.1 или localhost) - впоследствии я могу перейти в веб-браузер и запросить этот адрес:

http://127.0.0.1:8080/test.pl

... и я должен обратите внимание на print s, сделанные с помощью test.pl, загружаемых - и показаны - в веб-браузере.


Теперь, чтобы отладить этот скрипт с RemotePort, сначала нам понадобится слушателя в сети, через который мы будем взаимодействовать с отладчиком Perl; мы можем использовать инструмент командной строки netcat (nc, увиденный здесь: Perl 如何 удаленная отладка? ). Итак, сначала запустите прослушиватель netcat в одном терминале, где он будет блокировать и ждать подключения на порту 7234 (который будет нашим портом отладки):

$ nc -l 7234

Затем нам нужно perl для запуска в режиме отладки с RemotePort, когда test.pl был вызван (даже в режиме CGI, через сервер). Это можно сделать в Linux, используя следующий сценарий «shebang wrapper», который также должен находиться в /tmp, а должен быть выполнен :

cd /tmp

cat > perldbgcall.sh <<'EOF'
#!/bin/bash
PERLDB_OPTS="RemotePort=localhost:7234" perl -d -e "do '$@'"
EOF

chmod +x perldbgcall.sh

Это своего рода сложная вещь - см. Сценарий оболочки - Как я могу использовать переменные среды в моем shebang? - Unix & amp; Linux Stack Exchange . Но трюк здесь, кажется, не , чтобы развить интерпретатор perl, который обрабатывает test.pl - поэтому, как только мы его ударим, мы не exec, но вместо этого мы вызываем perl «прямо» и в основном «источник» нашего скрипта test.pl с использованием do (см. . Как запустить скрипт Perl из скрипта Perl? ).

Теперь что у нас есть perldbgcall.sh в /tmp - мы можем изменить файл test.pl, так что он ссылается на этот исполняемый файл на своей строке shebang (вместо обычного интерпретатора Perl) - здесь /tmp/test.pl изменено таким образом:

#!./perldbgcall.sh

# this is test.pl

use 5.10.1;
use warnings;
use strict;

my $b = '1';
my $a = sub { "hello $b there" };
$b = '2';
print "YEAH " . $a->() . " CMON\n";
$b = '3';
print "CMON " . &$a . " YEAH\n";

$DB::single=1;  # BREAKPOINT

$b = '4';
print "STEP " . &$a . " NOW\n";
$b = '5';
print "STEP " . &$a . " AGAIN\n";

Теперь оба test.pl и его новый обработчик shebang, perldbgcall.sh, находятся в /tmp; и мы nc слушаем отладочные соединения на порту 7234 - поэтому мы можем, наконец, открыть другое окно терминала, сменить каталог на /tmp и запустить веб-сервер с одним слоем (который будет прослушивать веб-соединения на порту 8080):

cd /tmp
perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'

После этого мы можем перейти в наш веб-браузер и запросить тот же адрес, http://127.0.0.1:8080/test.pl. Однако теперь, когда веб-сервер пытается выполнить скрипт, он сделает это через perldbgcall.sh shebang - который запустит perl в режиме удаленного отладчика. Таким образом, выполнение скрипта приостанавливается - и поэтому веб-браузер блокируется, ожидая данных. Теперь мы можем переключиться на терминал netcat, и мы должны увидеть знакомый текст отладчика Perl, однако вывести его через nc:

$ nc -l 7234

Loading DB routines from perl5db.pl version 1.32
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(-e:1):   do './test.pl'
  DB<1> r
main::(./test.pl:29):   $b = '4';
  DB<1>

. Как показывает фрагмент, теперь мы в основном используем nc как «терминал», поэтому мы можем ввести r (и Enter) для «run» - и скрипт будет запускаться с помощью инструкции breakpoint (см. также В perl, в чем разница между $ DB: : single = 1 и 2? ), прежде чем снова остановиться (обратите внимание, что в этот момент браузер все равно заблокируется).

Итак, теперь мы можем, скажем, пройти через остальные test.pl через терминал nc:

....
main::(./test.pl:29):   $b = '4';
  DB<1> n
main::(./test.pl:30):   print "STEP " . &$a . " NOW\n";
  DB<1> n
main::(./test.pl:31):   $b = '5';
  DB<1> n
main::(./test.pl:32):   print "STEP " . &$a . " AGAIN\n";
  DB<1> n
Debugged program terminated.  Use q to quit or R to restart,
  use o inhibit_exit to avoid stopping after program termination,
  h q, h R or h o to get additional info.
  DB<1>

... однако, также в этот момент браузер блокирует и ждет данных. Только после выхода из отладчика с q:

  DB<1> q
$

... блокирует блокировку браузера и, наконец, отображает (полный) вывод test.pl:

YEAH hello 2 there CMON
CMON hello 3 there YEAH
STEP hello 4 there NOW
STEP hello 5 there AGAIN

Конечно, такой отладочный процесс можно сделать даже без запуска веб-сервера, однако, в этом случае, мы не трогаем веб-сервер; мы запускаем выполнение «изначально» (для CGI) из веб-браузера - и единственным изменением, необходимым для самого скрипта CGI, является изменение shebang (и, конечно же, наличие скрипта оболочки shebang в качестве исполняемого файла в том же директория).

Ну, надеюсь, это поможет кому-то - я бы наверняка любил бы наткнуться на это, вместо того, чтобы писать сам :) Cheers!

7
ответ дан 3 revs 20 August 2018 в 20:07
поделиться

Используете ли вы обработчик ошибок во время отладки?

die операторы и другие фатальные ошибки времени выполнения и времени компиляции печатаются на STDERR, которые трудно найти и могут быть объединены с сообщениями с других веб-страниц вашего сайта. Хотя вы отлаживаете свой сценарий, неплохо было бы получить сообщения о фатальных ошибках для отображения в вашем браузере.

Один из способов сделать это - вызвать

   use CGI::Carp qw(fatalsToBrowser);

в верхней части вашего скрипта. Этот вызов установит обработчик $SIG{__DIE__} (см. perlvar ) отображает фатальные ошибки в вашем браузере, добавляя при необходимости допустимый заголовок. Другой трюк отладки CGI, который я использовал до того, как я когда-либо слышал о CGI::Carp, состоял в том, чтобы использовать eval с возможностями DATA и __END__ в скрипте для обнаружения ошибок времени компиляции:

   #!/usr/bin/perl
   eval join'', <DATA>;
   if ($@) { print "Content-type: text/plain:\n\nError in the script:\n$@\n; }
   __DATA__
   # ... actual CGI script starts here

Этот более подробный метод имеет небольшое преимущество перед CGI::Carp в том, что он будет ловить больше ошибок времени компиляции.

Обновление: я никогда не использовал его, но он выглядит как CGI::Debug , как предложил Mikael S, также является очень полезным и настраиваемым инструментом для этой цели.

7
ответ дан 4 revs, 2 users 98% 20 August 2018 в 20:07
поделиться
  • 1
    Я смотрю на этот фрагмент кода, пытаясь понять, как это работает ... – Ether 30 January 2010 в 05:18
  • 2
    @Ether: <DATA> - волшебный дескриптор файла, который читает текущий скрипт, начиная с __END__. Join предоставляет контекст списка, поэтому & lt; fh & gt; возвращает массив, по одной строке на элемент. Затем объединение объединяет его (соединяет его с ''). Наконец, eval. – derobert 9 September 2010 в 20:04
  • 3
    @Ether: более читаемым способом записи строки 2 будет: eval join(q{}, <DATA>); – derobert 9 September 2010 в 20:06
  • 4
    @derobert: на самом деле, __DATA__ - это токен, используемый для начала раздела данных, а не __END__ (я думаю, что это была моя путаница). – Ether 9 September 2010 в 20:17
  • 5
    @Ether: На самом деле, они оба работают в сценарии верхнего уровня (согласно man-странице perldata). Но поскольку DATA является предпочтительным, я изменил ответ. – derobert 10 September 2010 в 17:50

Честно говоря, вы можете сделать все самое интересное над этим сообщением. ALTHOUGH, самое простое и наиболее проактивное решение, которое я нашел, это просто «распечатать его».

В примере: (Обычный код)

`$somecommand`;

Чтобы узнать, делает ли он то, что я действительно хочу, чтобы он делал: (Устранение неполадок)

print "$somecommand";
1
ответ дан Ilan Kleiman 20 August 2018 в 20:07
поделиться

Для меня я использую log4perl . Это очень полезно и легко.

use Log::Log4perl qw(:easy);

Log::Log4perl->easy_init( { level   => $DEBUG, file    => ">>d:\\tokyo.log" } );

my $logger = Log::Log4perl::get_logger();

$logger->debug("your log message");
4
ответ дан zawhtut 20 August 2018 в 20:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: