Как вызвать асинхронный Perl-скрипт из CGI-файла с помощью system () - PullRequest
2 голосов
/ 06 октября 2019

Позвольте мне предвосхитить мой вопрос, сказав, что я ПРОЧИТАЛ множество различных постов по SO, а также по поиску в Интернете и не смог найти ничего, что соответствовало бы моей конкретной ситуации.

Проблема довольно проста, на самом деле,У меня есть CGI-скрипт (Perl), обслуживающий динамические страницы на веб-сервере, и когда пользователь загружает определенную страницу, я хочу, чтобы CGI-скрипт вызывал файл .pl, используя system(), чтобы выполнить некоторую «домашнюю работу». Это выполняется в среде Windows NT.

Сценарий CGI для целей тестирования: test1.pl или test1.cgi , например "https://www.awebsite.com/test1.pl".

test1.pl (сценарий cgi, который генерирует веб-страницы)

#!/usr/bin/perl

print "Content-type: text/html\n\n";

print "Hello user, this is a test page.";

system("start C:/path/to/script/test2.pl");

print "Page is fully loaded and housekeeping is being done, even though this page is now fully loaded";

test2.pl (отдельный файл .pl, выполняющий «ведение домашнего хозяйства»,асинхронно с тем, что делает test1.pl)

#!/usr/bin/perl

#just a counter that takes a while to complete, to verify test2.pl is running
for ($x=0; $x <= 100000; $x++){print "$x ";}

Хорошо, имейте в виду, что это для операций тестирования, а не функциональности. При запуске test1.pl из командной строки, он работает нормально.

При запуске test1.pl из браузера появляется сообщение «openWith.exe» на сервере (отображается в диспетчере задач). Мои файлы .pl являются исполняемыми, поэтому речь идет не о неизвестном типе файла или незнаниизапустить с интерпретатором командной строки Perl. Я не могу понять, что здесь происходит и почему он не будет запускать системную команду из test1.pl при вызове через веб-интерфейс.

НЕТ параметров, передаваемых из пользовательского ввода. test1.pl просто нужно запустить test2.plсделать некоторую домашнюю работу, но у меня не может быть test1.pl, ожидающего завершения test2.pl, прежде чем продолжить. Итак, test2.pl должен быть запущен test1.pl и продолжать работу - тем временем test1.pl уже завершил свою работу. Я не нуждаюсь или хочу захватить любой вывод из test2.pl.

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

Спасибо всем, кто может мне помочь. Кстати, я попытался установить разрешения «полный контроль» для test1.pl, и это не помогло. Опять же, этот "openwith.exe" действительно заставляет меня замолчать.

Ответы [ 3 ]

1 голос
/ 06 октября 2019

start C:/path/to/script/test2.pl полагается на настройку связи между файлами .pl и исполняемым файлом perl. Возможно, это настроено для вашего пользователя, но веб-сервер не может.

Вы можете настроить это. Или вы не можете использовать start и вместо этого напрямую передавать свою программу в perl. Как именно вы это сделаете, зависит от того, как установлен ваш Perl и настроен ваш веб-сервер. Возможно, вы сможете просто использовать perl.exe.

system('perl.exe C:/path/to/script/test2.pl');

. Или вам, возможно, придется пройти полный путь.

system('C:/path/to/perl.exe C:/path/to/script/test2.pl');

См. документацию для start для получения более подробной информации.


Обратите внимание, что запуск Perl-программ из Perl-программ не идеален. Существует множество трудных для отладки вещей, которые могут пойти не так, как только вы начнете передавать данные и проверять наличие ошибок.

Вместо этого рассмотрите возможность сделать этот код подпрограммой и использовать fork или threads для запуска его в фоновом режиме. Или, что еще лучше, используйте веб-фреймворк, например Dancer и , связав его с очередью заданий, например Minion .

1 голос
/ 07 октября 2019

Наконец-то разобрался (как обычно, самостоятельно). Оказывается, Шверн, вы были на правильном пути. Несмотря на то, что сопоставление файлов .pl было установлено через панель управления для открытия с помощью интерпретатора командной строки Perl, возникла проблема с сопоставлением типов файлов Windows (бла-бла, я даже не до конца понимаю). Наконец-то я нашел ответ на ИСТИННУЮ проблему: Perl не работает в Windows 10

В частности, эта часть здесь:

Вы должны создать файловую связь междуРасширение .pl и время выполнения Perl. В командной строке введите следующее.
assoc .pl=PerlScript
ftype PerlScript=c:\perl\bin\perl.exe %1 %*

Я надеюсь, что это поможет кому-то в будущем, кто может столкнуться с этой же проблемой.

0 голосов
/ 06 октября 2019

Вы можете оставаться в семантике окружения (cgi / web) и сделать script2 своим собственным CGI-скриптом, который вы затем запускаете асинхронным http-запросом в script1. Вы можете использовать HTTP::Async для этого. Но тогда вы должны позаботиться о том, чтобы script2 не вызывался извне, например, путем проверки ip клиента.

Кроме того, поскольку это cgi, script1 потенциально может запускаться несколько раз параллельно, то же самое касается и script2,как бы вы ни назвали этоПоэтому вы должны быть уверены, что не запутаетесь, когда это произойдет.

...