Помогите убить выполняемый скрипт

Sfrog

Новичок
Помогите убить выполняемый скрипт

В результате экспериментов по закачке файлов из интернета на свой сайт получил следующую ситуацию: давно запущенные (более 14 часов назад) скрипты все еще крутятся на сервере. Об этом свидетльствует то, что размер скачиваемых файлов постоянно увеличивается (если файл удалить - он снова появляется и растет с нуля). Кроме того в моем коде была ошибка, которая привела к тому, что размер этих файлов растет "в бесконечность", а не ограничивается размером скачиваемого файла.
Вопрос: как мне прибить выполенние этих скриптов, не обращаясь к хостеру?
Сокеты открывались через fsockopen.
Версия Apache 1.3.37 (Unix)
Версия MySQL 5.0.33-log
Версия PHP 5.2.0
Версия Cpanel 10.9.0-RELEASE-139
Версия cPanel Pro 1.0 (RC36)
 

Sfrog

Новичок
К сожалению, я не знаю о существовании такой функции в PHP. Есть posix_kill, но она требует идентификатора процесса, который мне неизвестен.
Если речь идет не о php, то не могли бы Вы уточнить, как именно можно воспользоваться этой командой?
 

Sfrog

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

magic

lancer
Sfrog
kill номер_процесса - это команда для консоли, на сервер запускать если есть ssh доступ.

Лучше исправь ошибку и рестартани апач.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Ты запускал их из shell или через браузер?
(в любом случае зайди на сервер по ssh или с консоли)

если из unix shell
#ps -A |grep php
это даст список текущих процессов php с их process id

если из браузера:
#apachectl stop
скорее всего это остановит твои скрипты, если нет
#ps -A |grep http
это даст список "зависших" процессов апача, в которых твой скрипт
(N.B. у Plesk, например, свои процессы, у Cpanel - не знаю, так что если есть панель - угадывай, где там твой скрипт)

прибиваешь #kill -9 process_id

process_id - число
 

Sfrog

Новичок
2grigori:
Запускал php-скрипт через браузер.
Прошу прощения за необразованность, а как туда зайти "по ssh или с консоли"? У меня ОС Windows.

-~{}~ 16.03.07 16:51:

2magic
Сайт у хостера, рестартнуть апач не могу, ssh-доступа нет :(
Думаю, что нет. Как проверить без обращения к хостеру?

А средствами PHP совсем никак?
 

Sfrog

Новичок
2tashkentchi
30, по умолчанию, хочешь - верь, хочешь - не верь.
И set_time_limit(0) я не ставил.

Но даже если ситуация через сутки и разрулится сама собой, все равно хотелось бы знать как отлавливать такие зависшие скрипты.
 

boombick

boombick.org
Код покажи. Я что-то не верю в такие скрипты незавершающиеся...
и вывод ps ax тоже.. Вывод можно получить через браузер:
PHP:
echo '<pre>';
system('ps ax');
echo '</pre>';
 

Sfrog

Новичок
2boombick
Код:
PHP:
<-------------------------------------------------------------------->
set_time_limit(360);

include "base_.php";
$query='select * from `downloads`';
$r=mysql_query($query) or die ("Invalid query 1-1 - ".$query." ".mysql_error());
if (!mysql_num_rows($r)) die ("нет задач для закачки");

for ($j=0; $j<mysql_num_rows($r); $j++) {
  $f=mysql_fetch_array($r);
  if (file_exists($f['FileName'])) $CurSize=filesize($f['FileName']); else $CurSize=0;
  if ($CurSize>=$f['FileSize'])  {
    $s="delete from `downloads` where `id`=".$f['ID'];
    mysql(DBName, $s) or die ("Oops - Не удалилось <br>$s<br>".mysql_error());
    die ("Удалена выполненная ранее задача, перезапустите скрипт");
  }
}


$r=mysql_query($query) or die ("Invalid query 1-1 - ".$query." ".mysql_error());
if (!mysql_num_rows($r)) die ("нет задач для закачки");
for ($j=0; $j<mysql_num_rows($r); $j++) {
  $f=mysql_fetch_array($r);
  if (file_exists($f['FileName'])) $CurSize=filesize($f['FileName']); else $CurSize=0;
  if ($CurSize<$f['FileSize']) {
    $turl=$f['URL'];

    $s=substr($turl, 0, 7);
    if ($s=="http://") {$turl=substr($turl, 7);};


    $server=substr($turl, 0, strpos($turl, '/'));
    $filename=substr($turl, strrpos($turl, '/')+1);
    $fullfile=substr($turl, strpos($turl, '/'));

    echo "server=$server"."<br>";
    echo "filename=$filename"."<br>";
    echo "fullfile=$fullfile"."<br>";

    while ($CurSize<$f['FileSize']) {
      $socket = fsockopen($server, 80); //коннект
      $s="GET $fullfile HTTP/1.0\r\nHOST: $server\r\n";
      if ($CurSize) $s.="Range: bytes=".($CurSize+1)."-\r\n";
      $s.="Connection: Close\r\n\r\n";
      fputs($socket, $s); //запрос
      echo "Отправляю запрос: $s<br>";
      while(fgets($socket,31337)!="\r\n" && !feof($socket)){unset($buffer); } //отбрасываем заголовок
      while(!feof($socket)) {
        $buffer=fread($socket, 1024); //читаем в переменную файл порциями по 1024 байт
        $ff=fopen($f['FileName'],"a+");//собственно, пишем в файл
        fwrite($ff, $buffer, strlen($buffer));
      }
      if (file_exists($f['FileName'])) $CurSize=filesize($f['FileName']); else $CurSize=0;
      if ($CurSize<$f['FileSize']) echo "обрыв связи, переконнекчиваюсь"; else echo "Файл ".$f['FileName']." загружен";
    }
  }
}
<-------------------------------------------------------------------->
ps ax можно увидеть здесь http://sfrog.dp.ua/close.php
 

boombick

boombick.org
таааак... а как вы определили, что скрипты качают? Вы смотрели. что они качают? Откуда они качают? Ну не может php-скрипт на шаред-хостинге неделю отработать!

На будущее: есть отличный тег для форума, называется
PHP:
Отредактируйте свое сообщение :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Как чудно хостер следит за безопасностью :)

set_time_limit(360) - это 360 секунд без учета времени ожидания соединения.
Недели тут не будет, конечно ... но если связь плохая и сокет "завис" - то и скрипт будет долго висеть.
$buffer=fread($socket, 1024) с блокирующим сокетом может висеть довольно долго.
Потом удаленный веб-сервер обрубает по тайм-лимиту, и начинается докачка по новому соединению :)
Я в подобных задачах обычно делаю лочку (lock, файл) и проверяю его существование на каждой итерации. Если файла нет - "группа подлежит самоликвидации" (С)

Какая-то мода на сокеты пошла ... почему не сделать это через file_get_contents(url) 2мя строками или CURL 4мя?

-~{}~ 16.03.07 22:34:

Да, по вопросу прибития. Отдели php-процессы "ps ax |grep php", выдели pid и позабивай их по циклу все :)
С таким уровнем безпасности на хостинге - нормально.
 

Gorynych

Посетитель PHP-Клуба
если PHP как модуль, то висеть могут процессы Апач и может не хватить прав

-~{}~ 17.03.07 00:02:

посмотрел вывод процессов по ссылке - сдается мне, что вот эта куча процессов /usr/local/apache/bin/httpd - оно самое и есть
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
А мне сдается, что это процессы php-cgi с заметным процессорным временем.
В противном случае - таки да, забить и запускать новый правильный скрипт.
Через неделю почистить, что они там накачали :)
 

Gorynych

Посетитель PHP-Клуба
1) мне кажется что принципиальной разницы (масса процессов имеет около 20 минут выполнения) нет
39534 ?? S 0:25.75 /usr/local/bin/php-cgi
43877 ?? S 0:17.80 /usr/local/bin/php-cgi
45974 ?? S 0:24.30 /usr/local/bin/php-cgi
48503 ?? S 0:27.01 /usr/local/bin/php-cgi
..
61524 ?? S 0:03.68 /usr/local/bin/php-cgi
64637 ?? S 0:20.60 /usr/local/apache/bin/httpd -DSSL
64642 ?? S 0:16.70 /usr/local/apache/bin/httpd -DSSL
64657 ?? S 0:18.57 /usr/local/apache/bin/httpd -DSSL
64663 ?? S 0:17.40 /usr/local/apache/bin/httpd -DSSL

2) честно говоря просто наблюдал такую ситуацию (массовый провис апач-процессов) в ситуации, когда PHP 4, собранный как модуль, подвисал при работе с PostgreSQL, так что просто высказал мысль по аналогии.

3) вообще-то мне сильно не нравится то, что у автора темы нет опыта работы с консолью. Может стоит обратиться в тех.поддержку?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
На самом деле, и апач может висеть ждать скрипта.
Я бы написал админам. Но захочет ли автор писать "я повесил 10 процессов, которые по циклу качают файлы из сети, перегрузите пожалуйста апач" ...
 

Sfrog

Новичок
К счастью за выходные ситуация таки разрулилась сама. То ли из-за того, что хостер чего-то перезагружал, то ли из-за того, что кончилось отведенное на хостинге дисковое пространство.
Огромное спасибо всем, принявшим участие, а grigori и boombick - особо огромное!

Автор оригинала: boombick
таааак... а как вы определили, что скрипты качают? Вы смотрели. что они качают?
Размер файлов постоянно растет. Признак вернейший :)
Автор оригинала: boombick
На будущее: есть отличный тег для форума, называется
PHP:
Отредактируйте свое сообщение :) [/QUOTE]
Спасибо за совет, но отредактировать не успел - время вышло :(
[QUOTE][i]Автор оригинала: grigori [/i]
Какая-то мода на сокеты пошла ... почему не сделать это через file_get_contents(url) 2мя строками или CURL 4мя? [/QUOTE]
Из мануала: "Использование функции file_get_contents() наиболее предпочтительно в случае необходимости получить содержимое файла целиком." А мне нужна была возможность докачки.
С cURL'oм буду разбираться.
[QUOTE][i]Автор оригинала: grigori [/i]
Да, по вопросу прибития. Отдели php-процессы "ps ax |grep php", выдели pid и позабивай их по циклу все 
С таким уровнем безпасности на хостинге - нормально. [/QUOTE]
Спасибо, это уже, по сути, конкретный алгоритм!
[QUOTE][i]Автор оригинала: grigori [/i]
Я в подобных задачах обычно делаю лочку (lock, файл) и проверяю его существование на каждой итерации. Если файла нет - "группа подлежит самоликвидации" (С)[/QUOTE]
Идея здравая, спасибо.  Этот же файл может служить флагом для недопущения повторного запуска скрипта, иначе в паре они такого накачают... ;)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Sfrog, это не идея, а принцип работы большинства служб Unix - создавать pid-файлы и .lock-файлы ;)

-~{}~ 20.03.07 16:29:

>А мне нужна была возможность докачки.
Читаю мануал ...
string file_get_contents ( string filename [, bool use_include_path [, resource context [, int offset [, int maxlen]]]] )

Если нет 5го PHP - лучше всего курл. У меня для него хороший класс-враппер есть, доки допишу - выложу :)
 
Сверху