Как я могу определить, был ли скрипт вызван из командной строки или как скрипт cgi? - PullRequest
8 голосов
/ 16 декабря 2009

У меня есть сценарий, который я написал, который можно использовать либо в командной строке, либо как сценарий CGI, и мне нужно определить, как вызывался сценарий, чтобы я мог выводить заголовок типа содержимого для веб-запросов (и, возможно, заголовки анти-кеша тоже). Моя первая мысль - проверить наличие переменных среды http:

my $js = build_javascript();

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

Есть ли лучший способ?

Ответы [ 3 ]

18 голосов
/ 16 декабря 2009

В соответствии со спецификацией CGI в RFC3875 (раздел 4.1.4.), Переменная среды GATEWAY_INTERFACE может использоваться для проверки того, работаете ли вы в контексте CGI:

4.1.4. GATEWAY_INTERFACE

Переменная GATEWAY_INTERFACE ДОЛЖНА быть установлена ​​на диалект CGI. используется сервером для связи со сценарием.

8 голосов
/ 16 декабря 2009

На самом деле нет никакого способа узнать, был ли ваш скрипт запущен веб-сервером или из командной строки. Любая из переменных среды может быть установлена ​​в обеих ситуациях. Например, я часто запускаю программы CGI прямо из командной строки, чтобы проверить их.

Зная, что если вы хотите выбрать одну переменную среды для использования, это просто должна быть та, которую вы не установите в другой ситуации, или та, которую вы задали в обеих, но присваиваете разные значения. В этом случае выберите любую переменную среды, которая вам нравится.

Если вы хотите стать более сложным, вы можете использовать что-то вроде IO :: Interactive , чтобы определить, подключены ли вы к терминалу. Если нет, то filehanandle, который возвращает is_interactive, является пустым дескриптором файла, и вывод не идет никуда:

 print { is_interactive() } $http_header;

Если вам не нравится, как решает IO :: Interactive , вы можете переопределить is_interactive. Это очень короткий кусок кода, и интерфейс более высокого уровня очень хорош.

2 голосов
/ 04 октября 2012

Я обычно делаю маленький трюк в начале моего модуля:

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».

...