Как использовать сценарий ожидания с веб-страницы php? - PullRequest
1 голос
/ 22 июня 2009

Когда я пытаюсь запустить программу из php5 на моем Debian, веб-страница останавливается, и программа ничего не делает. Этот скрипт работает, когда я вызываю его из командной строки. Безопасный режим отключен. Эхо 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 root@10.10.10.10:/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

Ответы [ 8 ]

1 голос
/ 15 декабря 2010

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

Мои симптомы были такими же, как у ОП. Я запускал 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-скрипт возвращал все выходные данные из сценария Expect):

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

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

1 голос
/ 29 июня 2009

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

1 голос
/ 22 июня 2009

Попробуйте

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

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

0 голосов
/ 13 сентября 2010
  1. Если вы используете exec вместо passthru, сделайте это следующим образом: exec ("/ bin / bash -c 'команда'> 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 из вашего кода и вуаля ..

0 голосов
/ 13 сентября 2010

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

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

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

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

0 голосов
/ 29 июня 2009

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

0 голосов
/ 29 июня 2009

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

0 голосов
/ 29 июня 2009

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

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

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

...