Исходя из кода в вашем вопросе, есть как минимум четыре варианта сбоя.
- У пользователя nobody нет разрешения на выполнение вашей программы.
- Код Perlв вашем вопросе нет строки shebang (
#!
).Вы пытаетесь запустить awk
, поэтому я предполагаю, что вы работаете в какой-то форме Unix.Если в вашем коде отсутствует эта строка, то ваша операционная система не знает, как запустить вашу программу. - Файл
s.txt
либо не находится в рабочем каталоге исполняемой программы, либо он не доступен для чтения никем.пользователь. - По какой-либо причине
awk
недоступен через PATH среды вашей исполняемой программы.
Чтобы быстро диагностировать такие проблемы низкого уровня, попробуйте устранить все ошибки.вывод, чтобы показать в браузере.Один из способов сделать это - добавить следующую строку сразу после строки shebang в вашем коде.
BEGIN {
print "Content-type: text/plain\n\n";
open STDERR, ">&", \*STDOUT or print "$0: dup: $!";
}
Вывод будет отображаться как обычный текст, а не как HTML, но это временная мера для просмотра вывода вашей программы.Оборачивая его в блок BEGIN
, код выполняется сразу после его анализа.Перенаправление STDERR
означает, что ваш браузер также получает что-либо записанное в стандартный вывод.
Другой способ сделать это - с помощью модуля CGI :: Carp .
use CGI::Carp 'fatalsToBrowser';
Таким образом, ошибки попадают в браузер, а также в журнал ошибок веб-сервера.
Если вы все еще видите ошибки 500-серии с вашего сервера, проблема происходит на более низком уровне: возможно, произошел сбой при запускеperl
.Зайдите в журнал ошибок вашего сервера.После выполнения вашей программы вы можете удалить это временное перенаправление вывода ошибок.
Наконец, я рекомендую изменить вашу программу на
#! /usr/bin/perl -T
BEGIN { print "Content-type: text/plain\n\n"; }
use strict;
use warnings;
$ENV{PATH} = "/bin:/usr/bin";
my $input = "/path/to/your/s.txt";
my $buckets = <<'EOProgram'
{ a[$1] += $2; b[$1] += $3 }
END { for (i in a) print i, a[i], b[i] }
EOProgram
open STDIN, "-|", "awk", $buckets, $input or die "$0: open: $!";
exec "sort", "-nk", 3 or die "$0: exec: $!";
Переключатель -T
включает анализ потока данных безопасности, называемый taint mode , который запрещает вам использовать неанизированный ввод для системных операций, таких как open
, exec
и т. Д., Которые злоумышленник (или обычный пользователь, предоставляющий неожиданный ввод) может использовать для нанесения вреда вашей системе.Вы всегда должны добавлять -T
в CGI-программы и любой другой код, который запускается от имени другого пользователя.
Учитывая характер вашей awk-программы, тип содержимого text / plain кажется разумным.Выведите его как можно скорее.
При включенном режиме taint укажите значение переменной окружения PATH.Если вместо этого вы придерживаетесь того ненадежного PATH, который унаследует ваша программа, попытка запуска внешних программ завершится неудачей.
Зафиксируйте полный путь ввода.Это исключит неожиданности.
Использование форм с несколькими аргументами open
и exec
устраняет оболочку и ее синтаксический анализ.(Для полноты system
также имеет аналогичную форму с несколькими аргументами.) Да, если написать это таким образом, это может означать, что будет немного более преднамеренным (например, разбив аргументы и настроив конвейер самостоятельно), но это также позволяет избежать неприятных сюрпризов.