Как запустить режим запуска 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, поскольку она должна работать только как контроллер. Разделяя эти биты, вы можете легко написать другие контроллеры для других методов ввода.

Не пишите веб-приложение; написать приложение, которое имеет веб-интерфейс. Когда у вас есть это, вы можете легко дать своему приложению другие виды интерфейсов.

Другие вопросы по тегам