【问题标题】:How can I determine if a script was called from the command line or as a cgi script?如何确定脚本是从命令行调用还是作为 cgi 脚本调用的?
【发布时间】:2010-12-27 06:18:54
【问题描述】:

我编写了一个脚本,它既可以在命令行上使用,也可以作为 CGI 脚本使用,并且需要确定脚本是如何被调用的,这样我才能为 Web 请求输出内容类型的标头(也许还有一些反缓存头)。我的第一个想法是检查http环境变量是否存在:

my $js = build_javascript();

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

有没有更好的办法?

【问题讨论】:

    标签: perl command-line cgi environment-variables


    【解决方案1】:

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

    4.1.4。 GATEWAY_INTERFACE

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

    【讨论】:

    • 我想是因为可能有其他类型的非 CGI 接口可能会设置 HTTP_HOST 环境变量。
    • 必须设置其他变量。但 HTTP_HOST 确实不是其中之一。
    • 这仍然没有帮助,因为您可以从命令行设置任何您喜欢的环境变量。
    • brian,通过设置 GATEWAY_INTERFACE,您是在说“我是 CGI 主机,所有关心的程序都应该相应地运行”。我看不出有任何理由在环境中“意外”设置它。否则,任何解决方案都不会有效,因为我可能会通过附加调试器来混淆程序,并弄乱实现所依赖的信息。
    【解决方案2】:

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

    知道,如果您想选择一个环境变量来使用,它必须是一个您不会在另一种情况下设置的变量,或者一个您同时设置但赋予不同值的变量。在这种情况下,请选择您喜欢的任何环境变量。

    如果您想变得更复杂,可以使用IO::Interactive 之类的东西来确定您是否连接到终端。如果不是,is_interactive 返回的文件句柄是一个空文件句柄,并且输出无处可去:

     print { is_interactive() } $http_header;
    

    如果您不喜欢 IO::Interactive 的决定方式,您可以重新实现 is_interactive。很短的一段代码,高层的界面也很不错。

    【讨论】:

      【解决方案3】:

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

      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”。

      【讨论】:

      • 欢迎来到 StackOverflow。如果您对某个答案改变了主意,请点击“删除”按钮,其他人都会看到它消失。
      猜你喜欢
      • 2011-02-09
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 2015-04-14
      • 1970-01-01
      相关资源
      最近更新 更多