Запустите perl-файл из PHP-скрипта, но не ждите вывода на Windows Server - PullRequest
1 голос
/ 26 ноября 2010

Я пытаюсь выполнить скрипт perl из скрипта php. У меня это работало с использованием различных методов, таких как exec, popen и proc_open, но у меня есть пара проблем, на которые старый добрый Google не дает мне ответов.

Мне нужно запустить скрипт .pl (передавая одну переменную скрипту, который является числом) из файла php, но не позволяя сценарию php ждать, пока не завершится .pl (вероятно, файл .pl займет 4 -5 часов работы на сервере). Я не ожидаю каких-либо возвращаемых результатов от сценария perl (сценарий perl записывает свой вывод в базу данных mysql), поэтому мне просто нужно, чтобы он был запущен на сервере и позволил сценарию php продолжить работу.

Существуют некоторые барьеры, которые необходимо преодолеть, поскольку он работает на компьютерах с Windows, работающих под управлением apache, php, mysql.

Я думаю, что видел решение для Linux, но оно должно оставаться на компьютере с Windows.

Я сейчас пытаюсь использовать метод proc_open, используя следующий код (35 в строке proc_open - это идентификатор теста, который мне нужно передать в скрипт perl):

$descriptorspec = array(
0 => array("pipe","r"),
1 => array("pipe","w"),
2 => array("file","./error.log","a")
) ;

proc_close(proc_open('perl perlscript.pl 35', $descriptorspec, $pipes));

$i = 0;
while ($i < 1000) {
   echo ++$i;  
}

Теперь этот код выполняет сценарий perl, но размещенный после него цикл while, помещенный после него (только для тестирования), никогда не выполняется (я не ждал, пока завершится сценарий perl, чтобы выяснить, выполняет ли он), поскольку он должен ожидать. PL до конца.

Ответы [ 4 ]

0 голосов
/ 29 ноября 2010

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

Поскольку это, кажется, что-то, что другие люди хотят знать, я подумал, что я поделюсь своим решением.

  1. Я скачал отсюда небольшую программу под названием Hstart (40kb): http://www.ntwind.com/software/utilities/hstart.html

  2. Я распаковал файлы в c: \ windows \ system32.

Программа hstart имеет возможность запускать пакетные файлы без открытия окна команд.Он не будет вызывать файл .pl напрямую, поэтому мне пришлось создать .bat для вызова .pl следующим образом.

  1. создал файл .bat в том же каталоге, что и мой файл .pl,в основном вызывается скрипт perl с использованием локально установленного perl и передачей переменной.Как показано здесь:

    perl script.pl% 1

  2. В моем скрипте PHP я использовал следующую команду для вызова моего файла perl.

    $cmd = 'hstart / NOCONSOLE "run.bat'. $ id. '"> log.log';exec ($ cmd);

  3. Запуск файла php приводит к открытию hstart с помощью noconsole из-за установленного флага, открытия файла perl с $ id, который я передал в качестве переменной, и отправки всехвывод скрытого консольного окна в log.log, как указано в моей команде.Все, что я вижу, - это perl.exe, запущенный в моем диспетчере задач.

Как я уже сказал, он далек от совершенства, но он работает.

0 голосов
/ 26 ноября 2010

Есть две возможности

  1. Использовать программу «Пуск». Вы не сможете использовать каналы, только аргументы командной строки.

  2. Создание постоянно работающей программы Perl (запускается при запуске или с использованием Win32 :: Daemon). Подключитесь к нему с помощью сокетов или http. Это легко, так как на CPAN имеется множество готовых серверов

Кроме того, это может быть возможно сделать из другой Perl-программы, используя Win32 :: Job или Win32 :: Process или другой модуль CPAN.

0 голосов
/ 28 ноября 2010

Я недавно опубликовал модуль для таких задач: Win32 :: Detached

Добавьте его в свой Perl-скрипт, и он будет демонизироваться, позволяя вашему PHP-скрипту двигаться дальше.

0 голосов
/ 26 ноября 2010

Я вижу 3 варианта:

  • Используйте fork в вашем скрипте perl, чтобы отключить фактическую работу с родительским процессом, существующим сразу после fork.Это может работать некорректно или вообще не работать в Windows, но стоит попробовать.

    Пожалуйста, ознакомьтесь со следующими ссылками "fork в Windows":

  • Если PHP может запустить запрос URL (аналогично Perl LWP или wget), то конвертируйтеСценарий Perl в сценарий CGI (тривиальный), вставьте его в каталог CGI вашего Apache и вызовите его по правильному URL-адресу http://localhost/....Затем тайм-аут запроса URL через некоторое внутреннее тайм-аут PHP или обычный HTTP тайм-аут в худшем случае.В ДЕЙСТВИТЕЛЬНО худшем случае проделайте тот же трюк из кода Perl, поскольку Perl может определенно поддерживать как URL-вызов через библиотеки LWP, так и тайм-аут через alarm()

  • Пусть планировщик запустит вашСкрипт Perl каждые X минут.Сценарий должен начинаться со следующей логики: if (-e $flag_file) { unlink $flag_file; do_long_work() } else { exit 0; }, где $flag_file - это специальное местоположение на сервере (скажем, C:\temp\myscript_start_perl.txt), а do_long_work() содержит фактическую работу, которую необходимо выполнить.

    Тогдакогда PHP-скрипт должен запустить Perl-скрипт, он просто создает пустой файл флага (тот же C:\temp\myscript_start_perl.txt), который будет замечен Perl-скриптом в следующий раз, когда планировщик выполнит его.

...