Как запустить режим запуска CGI::Application из командной строки?
В моем веб-приложении CGI::Application есть режим запуска, который я хотел бы запускать из командной строки, чтобы я мог автоматизировать его. С точки зрения веб-приложения оно выполняет некоторую обработку, а затем отправляет результаты по электронной почте.
При вызове из веб-интерфейса он передает набор параметров (адрес электронной почты, запрос для выполнения, дату и т. Д.), Поэтому их необходимо передать.
Как создать вызов приложения CGI::Application, который будет таким же, как если бы я запускал его из Интернета?
6 ответов
После дальнейшего изучения CGI::App и документации CGI, это оказалось более простым, чем я думал. Простейший случай (без реальной обработки аргументов или обработки выходных данных из вызова run Webapp):
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use WebApp;
my $cgi = new CGI( \%{@ARGV} );
my $webapp = WebApp->new( QUERY => $cgi );
$webapp->run();
Для создания CGI просто требуется ряд пар имен разделенных пробелами. Вам нужно передать в режиме запуска и все аргументы.
Оригинальная спецификация CGI позволяет легко запускать вещи из командной строки и была полностью задумана не как специальный интерфейс только для HTTP, а как что-то, что могло бы обрабатывать FTP и gopher, а также новые схемы URL верхнего уровня. Я знаю, что я хотел, когда я помог уточнить это.
Спецификация, на которую я ссылался, должна дать вам все, что вам нужно, но по большей части это просто набор переменных среды. Если вы видите запрос на:
http://some.server.com/some/path?a=b&c=d
Переменные среды выглядят так:
SERVER_PROTOCOL=http
REQUEST_METHOD=GET
HTTP_HOST=some.server.com
SERVER_PORT=80
PATH_INFO=/some/path
QUERY_INFO=a=b&c=d
Чтобы изменить полярность в Perl, нужно сделать что-то вроде этого:
$ENV{'SERVER_PROTOCOL'} = 'http';
$ENV{'REQUEST_METHOD'} = 'GET';
$ENV{'SERVER_PORT'} = 80;
$ENV{'PATH_INFO'} = '/some/path';
$ENV{'QUERY_INFO'} = 'a=b&c=d';
system("perl your-CGI-script.pl");
Вещи становятся немного более сложными в обработке запросов POST и есть больше возможных переменных среды, которые могут потребоваться. В худшем случае вы можете перечислить их все с помощью быстрого CGI-скрипта, например:
print "Content-Type: text/plain\r\n\r\n";
foreach (keys(%ENV))
{
print "$_=$ENV{$_}\r\n";
}
Теперь поместите это на веб-сервер вместо вашего CGI-скрипта, и вы увидите всю среду, которая будет передана (и исходную среду, поэтому вам нужно будет сделать несколько вызовов для оценки).
Я поддерживаю CGI::Application, и я делаю это все время - у меня есть дюжина скриптов cron, созданных с помощью CGI::Application, потому что удобно делить инфраструктуру с приложением.
Самый простой подход заключается в следующем:
# There is no browser to return results to.
$ENV{CGI_APP_RETURN_ONLY} = 1;
my $app = WebApp->new;
$app->direct_run_mode_method;
В этом примере вы обходите нормальный поток и вызываете метод напрямую. Убедитесь, что в этом случае вам не нужны какие-либо действия "установки" или "разрыва".
Если у вас есть только один режим запуска, который вы вызываете, вы также можете просто установить "start_mode" и вызвать run(), так что режим запуска по умолчанию вызывается по умолчанию.
Другая идея: вы можете использовать такой модуль, как Getopt::Long и передавать значения через хеш PARAM в new(), или полностью заменить процесс выбора режима выполнения. Вот пример, где флаги командной строки используются для определения режима выполнения:
sub setup {
my $self = shift;
$self->start_mode('send_error_digests');
$self->run_modes([qw/
send_error_digests
help
/]);
my ($dry_run, $help);
GetOptions(
'dry-run' => \$dry_run,
'help' => \$help
);
$self->param('dry_run' => $dry_run);
$self->mode_param(sub {
return 'help' if $help;
return $self->start_mode();
});
}
Thusly:
$ perl yourscript.pl field1=value1 field2=value2
Библиотека Perl CGI позаботится о вашем волшебстве, и похоже, что CGI::Application опирается на CGI (судя по их примеру кода).
Вы можете автоматизировать, вызвав веб-приложение, используя curl, wget или LWP GET-скрипт с соответствующими параметрами. Я использовал аналогичную систему для задач, управляемых cron, с приложением Catalyst.
Это касается всех переменных среды для вас..
Вместо того, чтобы проходить через CGI::Application каждый раз, когда вы хотите что-то сделать, используйте правильное разделение проблем, возможно, используя установку MVC. Вся функциональность должна существовать за пределами CGI::Application, поскольку она должна работать только как контроллер. Разделяя эти биты, вы можете легко написать другие контроллеры для других методов ввода.
Не пишите веб-приложение; написать приложение, которое имеет веб-интерфейс. Когда у вас есть это, вы можете легко дать своему приложению другие виды интерфейсов.