如何确定是从命令行还是作为cgi脚本调用脚本?

时间:2009-12-16 14:26:20

标签: perl command-line cgi environment-variables

我有一个我编写的脚本,可以在命令行上使用,也可以作为CGI脚本使用,需要确定脚本的调用方式,以便为Web请求输出内容类型的标题(也许是反缓存头也是)。我的第一个想法是检查http环境变量是否存在:

my $js = build_javascript();

if ( exists $ENV{HTTP_HOST} ) {
   print "Content-type: text/javascript\n\n";
}
print $js;

有更好的方法吗?

3 个答案:

答案 0 :(得分:18)

根据RFC3875(第4.1.4节)中的CGI规范,GATEWAY_INTERFACE环境变量将是检查您是否在CGI上下文中运行的权威事项:

  

4.1.4。 GATEWAY_INTERFACE

     

GATEWAY_INTERFACE变量必须设置为CGI的方言     被服务器用来与脚本通信。

答案 1 :(得分:8)

如果您的脚本是由Web服务器启动还是从命令行启动,那么确实无法判断脚本。可以在两种情况下设置任何环境变量。例如,我经常直接从命令行运行CGI程序来测试它们。

知道如果你想选择一个要使用的环境变量,它就必须是你不会在另一种情况下设置的环境变量,或者你在两者中设置但又给出不同值的环境变量。在这种情况下,请选择您喜欢的任何环境变量。

如果您想要更复杂,可以使用类似IO::Interactive的内容来确定您是否已连接到终端。如果不是,is_interactive返回的filehanandle是一个空文件句柄,输出无处可去:

 print { is_interactive() } $http_header;

如果您不喜欢IO::Interactive决定的方式,可以重新实施is_interactive。这是一段很短的代码,更高级的界面非常好。

答案 2 :(得分:2)

我通常在模块的开头做一个小技巧:

exit run(@ARGV) unless caller();   # run directly if called from command line

sub run
{
    process_options(@_);
    ...
}

sub process_options {
    @ARGV = @_;
    my  %opts;
    GetOptions(\%opts,
    ...
}

模块不必命名为“run”。