如何以编程方式创建新的CGI脚本并立即运行?

时间:2010-01-05 09:21:50

标签: perl cgi

我编写了一个Perl脚本来读取配置文件并创建CGI脚本。这工作正常,我在终端上获得CGI脚本的输出,我可以在网页上执行CGI脚本。以下是我的示例脚本。

#!/usr/bin/perl -w

use strict;
use Text::Template;

my $conf = "test.cfg";

open CFG, $conf or die "Could not open config file";
my @rawConfig = <CFG>;
my $config = eval "{".join("",@rawConfig)."}";

my $template = Text::Template->new(TYPE => 'FILE',  SOURCE => 'test.cgi.tmpl');
my $result = $template->fill_in(HASH => $config);
print $result;

通过使用它,我必须保存每个CGI并单独执行。我需要帮助才能修改此代码,以便我可以直接在Web上执行此脚本并在网页上显示输出。

2 个答案:

答案 0 :(得分:6)

这是一件非常非常可怕的事情,我通常建议不要做任何创造新程序的事情,让世界在没有人的地方运行它们。

但是,我怀疑您可能正在这样做,因为您创建的CGI脚本只需要不同的配置数据,并且您已将其存储在脚本本身中。这只是一个猜测,但它是这种事情的通常动力。答案是不在脚本中存储配置数据。我在Mastering Perl中有一整章关于不在代码中存储配置。

我很努力地避免你所描述的情况。

Does SO have a spoiler tag?)

如果您确实需要这么做(并且几乎不是这种情况),那么您将从原始进程创建文件,然后发出内部重定向到新的CGI脚本。你是如何做的那样是你的家庭作业,因为我不打算把枪弹给你。

答案 1 :(得分:2)

基于多个模板的脚本(几乎)从来都不是正确答案。

使用配置文件和控制结构中的数据结构来获取所需的行为。

而不是使用模板来创建如下代码:

sub foo {
    my $thing = shift;

    return blarg( $thing ) * feemb( $thing );
}

sub bar {
    my $thing = shift;

    return crag( $thing ) * forg( $thing );
}

sub baz {
    my $thing = shift;

    return chomb( $thing ) * veezle( $thing );
}

这样做:

# Get this from a config file.  YAML perhaps
my $cfg = {
    foo => [ \&blarg, \&feemb  ],
    bar => [ \&crag,  \&forg   ],
    baz => [ \&chomb, \&veezle ],
};

sub calculate_product {
    my $cfg   = shift;
    my $type  = shift;
    my $thing = shift;

    my @subs_to_call = @{ $cfg->{$type} || [] };

    my $result = {shift @subs_to_call}->($thing};

    $result *= $_->($thing) for @subs_to_call;

    return $result;
}
# Call like so:
my $foo_prod = calculate_product($cfg, 'foo', 15);

您可以通过使用配置信息生成闭包,将配置信息绑定到子例程(即'curry your functions'):

# Get this from a config file.  YAML perhaps
my $cfg = {
    foo => [ \&blarg, \&feemb  ],
    bar => [ \&crag,  \&forg   ],
    baz => [ \&chomb, \&veezle ],
};

my %calculate_product;
for my $product ( keys %$cfg ) {

    my @stored_subs_to_call = @{$cfg->{$product} || [] };

    $calculate_product{$prod} = sub {
        my $thing = shift;

        my @subs_to_call = @stored_subs_to_call;

        my $result = {shift @subs_to_call}->($thing};

        $result *= $_->($thing) for @subs_to_call;

        return $result;
    }
}

# Call generated code like so:
my $foo_prod = $calculate_product{foo}->(15);