5

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

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

我如何构造一个对 CGI::Application 应用程序的调用,它与我从 Web 上运行它时一样?

4

6 回答 6

6

最初的CGI 规范使得从命令行运行东西变得很容易,并且完全不是作为一个特定的 HTTP-only 接口,而是可以处理 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 脚本,您将看到传入的所有环境(以及原始环境,因此您需要进行一些判断调用)。

于 2009-07-17T00:41:51.670 回答
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 只需要一系列空格分隔的名称值对。您需要传入运行模式和所有参数。

于 2009-07-17T02:26:49.687 回答
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();
    });
}
于 2011-05-04T13:51:06.997 回答
0

因此:

$ perl yourscript.pl  field1=value1 field2=value2

Perl 的 CGI 库为您提供了魔法,看起来 CGI::Application 依赖于 CGI(从他们的示例代码来看)。

于 2009-07-16T23:42:14.830 回答
0

不必每次想要完成某事时都通过 CGI::Application 执行适当的关注点分离,也许使用MVC设置。所有功能都应该存在于 CGI::Application 之外,因为它只能作为控制器工作。分离出这些位后,您可以轻松地为其他输入法编写其他控制器。

不要编写 Web 应用程序;编写一个恰好具有 Web 界面的应用程序。当你拥有它时,你可以轻松地为你的应用程序提供其他类型的接口。

于 2009-07-16T23:45:24.853 回答
0

您可以通过使用 curl、wget 或带有适当参数的 LWP GET 脚本调用 Web 应用程序来实现自动化。我使用了一个类似的系统来处理具有 Catalyst 应用程序的 cron 驱动的任务。

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

于 2009-07-19T23:36:46.553 回答