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

时间:2022-12-15 20:44:18

I have a run mode in my CGI::Application web-app that I would like to be able to trigger from the command line so i can automate it. From the web-app's perspective it does some processing then sends the results in an email.

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

When called from the web interface it passes in a set of parameters (email address, which query to run, date, etc) so these need to be passed in.

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

How can I construct a call to the CGI::Application app that will be the same as if I ran it from the web?

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

6 个解决方案

#1


The original CGI specification makes it easy to run things from the command line and was fully intended not as a specific HTTP-only interface but something that could handle FTP and gopher as well as new top-level URL schemes. I know what I wanted when I helped specify it.

最初的CGI规范可以很容易地从命令行运行,完全不是作为特定的HTTP接口,而是可以处理FTP和gopher以及新的*URL方案。当我指示它时,我知道我想要什么。

The spec I referenced should give you all you need, but for the most part it is just a collection of environment variables. If you see a request for:

我引用的规范应该为您提供所需的一切,但在大多数情况下,它只是一组环境变量。如果您看到以下请求:

http://some.server.com/some/path?a=b&c=d

The environment variables come out looking like this:

环境变量看起来像这样:

SERVER_PROTOCOL=http
REQUEST_METHOD=GET
HTTP_HOST=some.server.com
SERVER_PORT=80
PATH_INFO=/some/path
QUERY_INFO=a=b&c=d

To reverse the polarity of that in Perl would go something like this:

要扭转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");

Things get a bit more complicated in handling POST queries and there are more possible environment variables that may be required. Worst case you can enumerate them all with a quick CGI script something like:

在处理POST查询时,事情变得更加复杂,并且可能需要更多可能的环境变量。最糟糕的情况是,您可以使用快速CGI脚本枚举它们,例如:

print "Content-Type: text/plain\r\n\r\n";
foreach (keys(%ENV))
{
    print "$_=$ENV{$_}\r\n";
}

Now put that on the web server in place of your CGI script and you'll see all the environment that gets passed in (and the original environment so you'll need to make a few judgement calls).

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

#2


Upon further digging through the CGI::App and the CGI documentation, it appeared to be more straightforward than I thought. The simplest case (no real argument handling or dealing with the output from the webapp run call) is:

在进一步挖掘CGI :: App和CGI文档后,它似乎比我想象的更直接。最简单的情况(没有真正的参数处理或处理来自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();

It just takes a series of space separated name value pairs to create the CGI. You need to pass in the run mode and all the arguments.

它只需要一系列空格分隔的名称值对来创建CGI。您需要传入运行模式和所有参数。

#3


I'm the maintainer of CGI::Application, and I do this all the time-- I have dozen of cron scripts built with CGI::Application because it's convenient to share the infrastructure with the application.

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

The simplest approach is this:

最简单的方法是:

# There is no browser to return results to.
$ENV{CGI_APP_RETURN_ONLY} = 1;

my $app = WebApp->new;
$app->direct_run_mode_method;

In that example, you bypass the normal flow and call a method directly. Be sure you don't need any of the "setup" or "teardown" actions to happen in that case.

在该示例中,您绕过正常流并直接调用方法。在这种情况下,请确保您不需要执行任何“设置”或“拆卸”操作。

If you just have one run mode you are calling, you can also just set the "start_mode", and call run(), so then the default run mode is called by default.

如果您只有一个正在调用的运行模式,您也可以设置“start_mode”,并调用run(),这样默认情况下会调用默认的运行模式。

Another idea: you can use a module like Getopt::Long and pass in values through the PARAM hash to new(), or completely replace the run-mode selection process. Here's an example where command line flags are used to determine the run mode:

另一个想法是:您可以使用像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();
    });
}

#4


Thusly:

$ perl yourscript.pl  field1=value1 field2=value2

Perl's CGI library takes care of the magic for you, and it appears that CGI::Application relies on CGI (judging from their example code).

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

#5


Instead of having to go through CGI::Application every time you want to get something done, enforce a proper separation of concerns, perhaps using an MVC setup. All of the functionality should exist outside of the CGI::Application stuff since that should only work as a controller. Once you separate out those bits, you can easily write other controllers for other input methods.

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

Don't write a web application; write an an application that happens to have a web interface. When you have that, you can easily give your application other sorts of interfaces.

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

#6


You could automate by calling the web app using curl, wget, or an LWP GET-script with the appropriate parameters. I've used a similar system for cron-driven tasks with a Catalyst application.

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

That deals with all the environment variables for you..

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

#1


The original CGI specification makes it easy to run things from the command line and was fully intended not as a specific HTTP-only interface but something that could handle FTP and gopher as well as new top-level URL schemes. I know what I wanted when I helped specify it.

最初的CGI规范可以很容易地从命令行运行,完全不是作为特定的HTTP接口,而是可以处理FTP和gopher以及新的*URL方案。当我指示它时,我知道我想要什么。

The spec I referenced should give you all you need, but for the most part it is just a collection of environment variables. If you see a request for:

我引用的规范应该为您提供所需的一切,但在大多数情况下,它只是一组环境变量。如果您看到以下请求:

http://some.server.com/some/path?a=b&c=d

The environment variables come out looking like this:

环境变量看起来像这样:

SERVER_PROTOCOL=http
REQUEST_METHOD=GET
HTTP_HOST=some.server.com
SERVER_PORT=80
PATH_INFO=/some/path
QUERY_INFO=a=b&c=d

To reverse the polarity of that in Perl would go something like this:

要扭转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");

Things get a bit more complicated in handling POST queries and there are more possible environment variables that may be required. Worst case you can enumerate them all with a quick CGI script something like:

在处理POST查询时,事情变得更加复杂,并且可能需要更多可能的环境变量。最糟糕的情况是,您可以使用快速CGI脚本枚举它们,例如:

print "Content-Type: text/plain\r\n\r\n";
foreach (keys(%ENV))
{
    print "$_=$ENV{$_}\r\n";
}

Now put that on the web server in place of your CGI script and you'll see all the environment that gets passed in (and the original environment so you'll need to make a few judgement calls).

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

#2


Upon further digging through the CGI::App and the CGI documentation, it appeared to be more straightforward than I thought. The simplest case (no real argument handling or dealing with the output from the webapp run call) is:

在进一步挖掘CGI :: App和CGI文档后,它似乎比我想象的更直接。最简单的情况(没有真正的参数处理或处理来自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();

It just takes a series of space separated name value pairs to create the CGI. You need to pass in the run mode and all the arguments.

它只需要一系列空格分隔的名称值对来创建CGI。您需要传入运行模式和所有参数。

#3


I'm the maintainer of CGI::Application, and I do this all the time-- I have dozen of cron scripts built with CGI::Application because it's convenient to share the infrastructure with the application.

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

The simplest approach is this:

最简单的方法是:

# There is no browser to return results to.
$ENV{CGI_APP_RETURN_ONLY} = 1;

my $app = WebApp->new;
$app->direct_run_mode_method;

In that example, you bypass the normal flow and call a method directly. Be sure you don't need any of the "setup" or "teardown" actions to happen in that case.

在该示例中,您绕过正常流并直接调用方法。在这种情况下,请确保您不需要执行任何“设置”或“拆卸”操作。

If you just have one run mode you are calling, you can also just set the "start_mode", and call run(), so then the default run mode is called by default.

如果您只有一个正在调用的运行模式,您也可以设置“start_mode”,并调用run(),这样默认情况下会调用默认的运行模式。

Another idea: you can use a module like Getopt::Long and pass in values through the PARAM hash to new(), or completely replace the run-mode selection process. Here's an example where command line flags are used to determine the run mode:

另一个想法是:您可以使用像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();
    });
}

#4


Thusly:

$ perl yourscript.pl  field1=value1 field2=value2

Perl's CGI library takes care of the magic for you, and it appears that CGI::Application relies on CGI (judging from their example code).

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

#5


Instead of having to go through CGI::Application every time you want to get something done, enforce a proper separation of concerns, perhaps using an MVC setup. All of the functionality should exist outside of the CGI::Application stuff since that should only work as a controller. Once you separate out those bits, you can easily write other controllers for other input methods.

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

Don't write a web application; write an an application that happens to have a web interface. When you have that, you can easily give your application other sorts of interfaces.

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

#6


You could automate by calling the web app using curl, wget, or an LWP GET-script with the appropriate parameters. I've used a similar system for cron-driven tasks with a Catalyst application.

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

That deals with all the environment variables for you..

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