Как использовать сценарий ожидания с веб-страницы php?

Когда я пытаюсь запустить программу из php5 на моем Debian, веб-страница зависает, и программа ничего не делает. Этот скрипт работает, когда я вызываю его из командной строки. Безопасный режим отключен. Echo stdout не работает (из-за зависания). Я прочитал несколько ответов в Google, в которых говорится о разрешениях www, но если у кого-то здесь есть быстрый и простой ответ...

Как это отладить?

PHP-вызов

exec("expect scripts/sshtest.exp $module");

Код скрипта (который я нашел здесь http://bash.cyberciti.biz/security/expect-ssh-login-script/)

#!/usr/bin/expect -f
# set Variables
set module [lrange $argv 0 0]
set timeout -1
# rsync 
spawn rsync -aCb --progress --delete --backup-dir=/var/www/blabla.com/rsyncBackups/BackupedFilesFromServer23_on_  /var/www/blabla/$module  -e ssh [email protected]:/root/$module
match_max 1000000
# Look for passwod prompt
expect "*?assword:*"
# Send password 
send -- "THEPASSWORD\r"
# send blank line (\r) to make sure we get back to gui
send -- "\r"
expect eof

person belaz    schedule 22.06.2009    source источник
comment
Что вы имеете в виду под заморозкой? Вы имеете в виду, что веб-страница не будет загружаться в вашем браузере, она загружается вечно и не возвращает сайт? Или это означает, что сам браузер завис и не отвечает? Или что-то совсем другое?   -  person Andrew Dunkman    schedule 24.06.2009


Ответы (8)


Пытаться

passthru("expect scripts/sshtest.exp $module 2>&1");

2>&1 перенаправляет stderr на stdout, а использование passthru вместо exec даст вам все выходные данные.

person Greg    schedule 22.06.2009
comment
заморозить, не позволяйте мне видеть вывод. - person belaz; 22.06.2009

Зачем вообще использовать ожидание? Настройте rsync для использования открытых/закрытых ключей (см. http://troy.jdmz.net/rsync/index.html), и вам не нужно будет использовать expect для ввода паролей.

person Marie Fischer    schedule 29.06.2009

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

Мои симптомы были такими же, как и при ОП. Я запускал PHP-скрипт, он запускал Expect-скрипт через shell_execute, а потом он просто зависал навсегда. Проблема оказалась из-за следующего вопроса, который задавался пользователю apache при запуске скрипта Expect:

Подлинность хоста «xx.xx.xx.xx (xx.xx.xx.xx)» не может быть установлена. Отпечаток ключа RSA — ххххх. Вы уверены, что хотите продолжить подключение (да/нет)?

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

Чтобы решить эту проблему, я добавил этот код перед тем местом, где я ввел пароль:

expect "*you sure you want to continue*"
send -- "yes\r"

Это привело к следующему (мой PHP-скрипт вернул все выходные данные из ожидающего скрипта):

Подлинность хоста «xx.xx.xx.xx (xx.xx.xx.xx)» не может быть установлена. Отпечаток ключа RSA — ххххх. Вы уверены, что хотите продолжить подключение (да/нет)? да Не удалось добавить хост в список известных хостов (/var/www/.ssh/known_hosts).

Однако сразу после этого появилось приглашение ввести пароль, и пароль был введен правильно. С этого момента скрипт Expect работал нормально.

person patorjk    schedule 15.12.2010
comment
Это сработало и для меня, но я все еще ищу способ обойти это, поскольку я не хочу, чтобы этот вывод был на веб-странице. - person Dave Noonan; 25.06.2013

Еще одна распространенная проблема заключается в том, что когда вы запускаете команду, вы являетесь пользователем, отличным от того, когда apache запускает команду. И часто пользовательский apache запускается с очень ограниченными настройками по соображениям безопасности.

например. Возможно, у пользователя apache не установлены правильные пути. Используйте абсолютный путь для ожидания, а не относительный. Вы можете найти это, запустив «который ожидает».

Попробуйте выполнить «su» для того же пользователя, с которым работает apache (найдите команду «User» в файле конфигурации apache или просто просмотрите «ps aux»), запустите команду и посмотрите, какие ошибки вы получаете.

person James    schedule 29.06.2009

«Пользователь» или «группа», которые PHP использует для выполнения команд, могут иметь недостаточные права для выполнения одной команды в сценарии (или даже ожидать самого себя). Пробовали ли вы использовать sudo для запуска скрипта от имени того же пользователя, с которым вы тестировали?

person timdel    schedule 29.06.2009

Используете ли вы mod___php или suPHP?
mod_php запускает скрипты от имени пользователя Apache, поэтому попробуйте выполнить команду su для пользователя apache, а затем запустить php-скрипт из оболочки "php scriptname.php" и посмотреть, работает ли он.
Если вы используйте suPHP, затем su для пользователя, под которым вы настроили apache, чтобы настроить эти скрипты и то же самое «php scriptname.php» и проверить вывод.

person daniels    schedule 29.06.2009

Будьте осторожны с ожиданием того, что php вы ждете достаточно долго, прежде чем вводить следующую команду, а также что все ваши переменные верны. Указатель Грега на использование 2>&1 избавил меня от многих хлопот.

попробуй запустить

passthru("expect -d scripts/sshtest.exp $module");

-d спасет вашу жизнь в ожидании.

person P O'Conbhui    schedule 12.09.2010

  1. Если вы используете exec вместо passthru, сделайте это следующим образом: exec("/bin/bash -c 'command' > logfile_to_read_or_include_next");

  2. Если вы хотите испортить свою систему порожденными процессами:

написать perl/c скрипт, который будет обрабатывать ваши запросы.

#!/usr/bin/perl -w
use HTTP::Daemon;
use HTTP::Status;
use strict;
  my $d = HTTP::Daemon->new(LocalPort => 10050) || die;
  print "Please contact me at: <URL:", $d->url, ">\n";
  while (my $c = $d->accept) {
      while (my $r = $c->get_request) {
          if ($r->method eq 'GET' and $r->uri->path =~/addRequest-(.*)$/) {
                # variable $1 now has your request.
                 my $rq = $1; # wash me!
                # assign it a #ID, 
                 my $id = "id".time().rand(100);
                 &run_in_another_thread($rq,$id);
              $c->send_responce($id);
          } elsif ($r->method eq 'GET' and $r->uri->path =~/seeRequest-(.*)$/) {
             $c->send_responce( &get_result_for_id($1) );
          }
          else {
              $c->send_error(RC_FORBIDDEN)
          }
      }
      $c->close;
      undef($c);
  }
}

sub run_in_another_thread {
 my ($rq,$id) = @_;
 my $evil = threads->create( sub { qx"/bin/bash -c '$rq' > logfile_$id.log" # start process
  }->detach();
}

sub get_result_for_id {
 my ($id) = @_;
 return qx"cat logfile_$id.log";
}

Затем получите 127.0.0.1/addRequest-expect из своего кода и вуаля.

person kagali-san    schedule 12.09.2010