Как запустить сценарий оболочки с обратной связью с PHP?

Как мне выполнить сценарий оболочки из PHP, давая постоянную/живую обратную связь с браузером? Я понимаю из документации по функциям system:

Вызов system() также пытается автоматически очищать буфер вывода веб-сервера после каждой строки вывода, если PHP работает как серверный модуль.

Я не понимаю, что они имеют в виду, запуская его как «серверный модуль».

Пример PHP-кода:

<?php

system('/var/lib/script_test.sh');

Пример шелл-кода:

#!/bin/bash

echo "Start..."
for i in {1..10}
do
        echo "$i..."
        sleep 1
done
echo "Done."

Что это делает: он будет ждать около 10 секунд, а затем сбрасывать в выходной буфер.

Что я хочу сделать: Сбрасывать в выходной буфер после каждой строки вывода.


person Highway of Life    schedule 20.03.2012    source источник
comment
серверный модуль = PHP, встроенный в веб-сервер (например, mod_php), и не работающий в режиме «cgi».   -  person Marc B    schedule 20.03.2012


Ответы (2)


Это можно сделать с помощью popen(), который дает вам дескриптор стандартного вывода любой процесс, который вы открываете. Блоки данных могут быть отправлены клиенту с помощью ob_flush(), данные могут отображаться с помощью XHR.

person rook    schedule 20.03.2012
comment
Конечно, браузер не обязан ОТОБРАЖАТЬ его по мере его поступления. На самом деле лучше всего было бы использовать опрос ajax или что-то в этом роде и фактически запустить процесс неблокирующим образом. - person Tyler Eaves; 20.03.2012
comment
@TylerEaves, хорошие мысли. Хотя я использую вызов AJAX для загрузки страницы PHP, на которой выполняется сценарий оболочки, поэтому, если я могу постоянно сбрасывать с помощью popen(), это было бы идеально для моей ситуации. - person Highway of Life; 20.03.2012
comment
То, как я сделал это в приложении, которое я реализовал (но не PHP), заключалось в том, чтобы назначить идентификатор задания на внешней странице, а затем у меня была таблица со структурой jobid / message / timestamp (целочисленный стиль Unix). Для каждой строки/группы вывода я вставляю в таблицу сообщений. Каждую секунду (это было приложение для интрасети, поэтому задержка была низкой). Я опросил через ajax, передав идентификатор задания и метку времени последнего обработанного сообщения, и вернул массив json меток времени и текста. Подготовил текст к моему сообщению div. Сделанный. Простой. Будет работать для нескольких пользователей. - person Tyler Eaves; 20.03.2012
comment
@Highway of Life Да, это идея. - person rook; 20.03.2012
comment
XHR в Internet Explorer не позволит вам прочитать частичный ответ, поэтому в IE вы получите информацию на странице только после полного завершения сценария оболочки. См.: http://css.dzone.com/articles/partial-xmlhttprequest - person MrCode; 20.03.2012

Один из вариантов - писать в файл в сценарии оболочки, чтобы на каждом шаге говорить, где он находится. На вашей веб-странице используйте вызов ajax каждые X секунд/минут. Вызов ajax вызовет PHP-скрипт, который читает файл состояния и возвращает статус или завершенные шаги.

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

Недостатком, конечно, является то, что чем больше интервал ajax, тем более устаревшим будет обновление.

person MrCode    schedule 20.03.2012
comment
Файл избыточен, поэтому существует popen и обработчики stdout. - person rook; 20.03.2012
comment
Ситуации, в которых требуется доступ к файлу вместо popen, включают, помимо прочего: цепочку между сценариями, потоки данных в реальном времени, трансляцию результатов xhr. - person Garet Claborn; 16.11.2013