如何从命令行运行CGI :: Application运行模式?

时间:2009-07-16 23:39:07

标签: perl cgi-application

我的CGI::Application网络应用程序中有一个运行模式,我希望能够从命令行触发,以便我可以自动执行它。从web-app的角度来看,它会进行一些处理,然后通过电子邮件发送结果。

从Web界面调用时,它会传递一组参数(电子邮件地址,要运行的查询,日期等),因此需要传入这些参数。

如何构建对CGI :: Application应用程序的调用,就像我从Web上运行它一样?

6 个答案:

答案 0 :(得分:6)

原始的CGI specification可以很容易地从命令行运行,完全不是作为特定的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";
}

现在将它放在Web服务器上代替您的CGI脚本,您将看到所有传入的环境(以及原始环境,因此您需要进行一些判断调用)。

答案 1 :(得分:3)

在进一步挖掘CGI::AppCGI文档后,它似乎比我想象的更直接。最简单的情况(没有真正的参数处理或处理来自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。您需要传入运行模式和所有参数。

答案 2 :(得分:3)

我是CGI :: Application的维护者,我一直这样做 - 我有十几个用CGI :: Application构建的cron脚本,因为它可以方便地与应用程序共享基础设施。

最简单的方法是:

# 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();
    });
}

答案 3 :(得分:0)

所以:

$ perl yourscript.pl  field1=value1 field2=value2

Perl的CGI库为您处理魔术,CGI :: Application似乎依赖于CGI(从他们的示例代码判断)。

答案 4 :(得分:0)

每次想要完成某项工作时,不必经过CGI :: Application,而是使用separation of concerns设置强制执行MVC。所有功能都应该存在于CGI :: Application之外,因为它只能作为控制器使用。分离出这些位后,您可以轻松地为其他输入方法编写其他控制器。

不要编写Web应用程序;编写一个恰好具有Web界面的应用程序。有了这些,您可以轻松地为您的应用程序提供其他类型的接口。

答案 5 :(得分:0)

您可以使用curl,wget或带有适当参数的LWP GET脚本调用Web应用程序来自动执行。我在Catalyst应用程序中使用了类似的cron驱动任务系统。

它为您处理所有环境变量..