2014-06-04 1 views
2

Я бы сказал, что это довольно простой вопрос, но я застрял с ним:Go интерактивного внешней программой из PHP

мне нужно общаться с внешней программой (в частности, Exim) запускать с некоторыми опциями отладки. Когда я запускаю его из оболочки linux, он выглядит следующим образом: запустите exim -bh 11.22.33.44, затем прочитайте его вывод (как STDOUT, так и STDERR), тип в некоторой строке из диалога SMTP, затем снова прочитайте вывод Exim, введите другую строку SMTP и так далее. И это хорошо работает, пока я нахожусь в оболочке bash, но когда я запускаю его из скрипта PHP, он застревает в цикле чтения STDIN.

Я использую proc-open:

$descriptorspec = array(
    0 => array("pipe", "r"), 
    1 => array("pipe", 'w'), 
    2 => array("pipe", 'w') 
); 
$process=proc_open('/usr/sbin/exim -bh 11.22.33.44', $descriptorspec, $pipes, NULL, NULL); 
if (is_resource($process)) { 
    stream_set_blocking($pipes[1], 1); 
    stream_set_blocking($pipes[2], 1); 
    while(!feof($pipes[2])) { 
     $txt2 = fgets($pipes[2]); 
    } 
    while(!feof($pipes[1])) { 
     $txt2 = fgets($pipes[1]); 
    } 
    fwrite($pipes[0], 'HELO testhost'); 
... 
} 

Выглядит просто, но, как она идет к концу первого STDERR, он застрял.

Пробовал блокировать и разблокировать режим, пытался обменять чтение из STDERR и STDIN - пока не повезло.

Пожалуйста, укажите мне правильный путь!

ответ

0

Я проверяю дважды, чтобы убедиться, что exim не делает ничего интересного с STDIN, STDOUT и STDERR. Кроме того, я знаю, что вы можете использовать swaks для подключения к STDIN и STDOUT (STDERR - это отладочный вывод, поэтому вы можете игнорировать это). С swaks, это общие для проверки отладки сборок с такими командами, как:

swaks --pipe './build-Linux-i386/exim -bh 205.201.128.129 
       -C/work/home/exim-build/tmp/etc/exim/exim.conf' 
    --ehlo twitter4.us4.mcsv.net 
    --from [email protected].net 
    --to [email protected] --data $HOME/12.eml 

Ваш скрипт проверки на EOF, который посылается только тогда, когда труба закрыта. Вместо этого вам нужно построить функцию, которая проверяет внешний цикл для проверки() на! Eof() из одной из труб. Внутри цикла проверьте вывод из STDERR и STDOUT и отобразите его, если он найден. Когда он доберется до точки, где он ожидает ввода, отправьте свои SMTP-команды.

Однако все еще существует проблема. Если вы используете print $ txt2, чтобы увидеть, что он делает, как-то этот вывод кажется таким же, как fprintf ($ pipes [0] ...). Я не уверен, почему, и я не программист php, чтобы знать, почему это будет сделано.

+0

Проблема заключается в том, что когда я использую режим блокирующих труб, мой скрипт зависает на последней итерации 'fgets()' (то есть, он будет ждать больше данных), когда я устанавливаю режим для разблокировки, t получить (все) текст вообще, поскольку я возвращаюсь довольно быстро. Кстати, спасибо за 'swaks', во всяком случае, никогда не поздно узнать что-то новое! – Alexander

Смежные вопросы