代码之家  ›  专栏  ›  技术社区  ›  Todd Hunter

如何从命令行运行CGI::应用程序运行模式?

  •  5
  • Todd Hunter  · 技术社区  · 17 年前

    我有一个运行模式在我的 CGI::Application 我希望能够从命令行触发的Web应用程序,这样我就可以自动执行它。从Web应用的角度来看,它会做一些处理,然后将结果发送到电子邮件中。

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

    如何构造对cgi::application应用程序的调用,使其与从Web上运行的调用相同?

    6 回复  |  直到 15 年前
        1
  •  6
  •   brian d foy    17 年前

    原文 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脚本,您将看到所有传入的环境(以及原始环境,因此您需要进行一些判断调用)。

        2
  •  3
  •   ysth    17 年前

    在进一步挖掘 CGI::App 以及 CGI 文档,看起来比我想象的更直接。最简单的情况(没有真正的参数处理或处理webapp run调用的输出)是:

    #!/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。您需要在运行模式和所有参数中传递。

        3
  •  3
  •   Mark Stosberg    15 年前

    我是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”和call run(),这样默认的运行模式就会被调用。

    另一个想法是:可以使用getopt::long这样的模块,并通过param hash将值传递给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();
        });
    }
    
        4
  •  0
  •   markh    17 年前

    因此:

    $ perl yourscript.pl  field1=value1 field2=value2
    

    Perl的cgi库为您提供了魔力,而且看起来cgi::应用程序依赖于cgi(从它们的示例代码判断)。

        5
  •  0
  •   brian d foy    17 年前

    不必每次完成某项任务时都要检查cgi::application,而是强制 separation of concerns ,可能使用 MVC 设置。所有的功能都应该存在于CGI::应用程序之外,因为它只能作为控制器工作。一旦分离出这些位,就可以轻松地为其他输入方法编写其他控制器。

    不要编写Web应用程序;编写一个恰好有Web界面的应用程序。当你有了它,你可以很容易地给你的应用程序提供其他种类的接口。

        6
  •  0
  •   sidler    17 年前

    通过使用curl、wget或带有适当参数的lwp get脚本调用Web应用程序,可以实现自动化。我使用了一个类似的系统来完成cron驱动的任务和Catalyst应用程序。

    它为您处理所有的环境变量。

    推荐文章