Поймать выходы PHP в CLI через sh - PullRequest
1 голос
/ 31 января 2011

Хорошо, я пытаюсь решить эту проблему. У меня есть класс, который зацикливается до бесконечности, пока я либо не перезапущу его вручную, либо у него не закончится доступная память. Я написал код для совместимости как с CLI, так и с обычным веб-исполнением. Единственное отличие состоит в том, что при выполнении через Интернет сценарий будет длиться около 12 часов или около того, пока не завершится сбоем из-за проблем с памятью. Когда я запускаю его в CLI, он работает намного дольше (в среднем за 4-5 дней до сбоя из-за памяти)

Скрипт - это IRC-бот, который сильно настроен для того, что мне нужно. Я не знаю достаточно C ++, ruby, python или других языков, чтобы сделать что-то, что является кросс-платформенным. Моя машина разработки - Windows, а мой рабочий сервер - Ubuntu. Прямо сейчас у меня есть сценарий, успешно разветвляющийся и отсоединяющийся от окна терминала, так что я могу закрыть его без завершения сценария.

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

Вот мой скрипт php запуска CLI

#!/usr/bin/php
<?php

include_once ("./config/base_conf.php");
include_once ("./libs/irc_base.php");

if ($config ['database'] == true) {
    include_once ("./config/db_conf.php");
}
$server = getopt ( 's', array ("server::" ) );

if (! $server) {
    $SER = 'default_server';
} elseif ($server ['server'] == 'raelgun') {
    $SER = 'server_a';
} else {
    $SER = 'default_server';
}

declare ( ticks = 1 )
    ;
$pid = pcntl_fork ();
if ($pid == - 1) {
    die ( "could not fork" );
} else if ($pid) {
    exit (); // we are the parent
} else {
    // we are the child
}
// detatch from the controlling terminal
if (posix_setsid () == - 1) {
    die ( "could not detach from terminal" );
}
$posid = posix_getpid ();
$PID_FILE = "/var/run/bot_process_".$SER.".pid";
$fp = fopen ($PID_FILE , "w" ) or die("File Exists Process Running");
fwrite ( $fp, $posid );
fclose ( $fp );
// setup signal handlers
pcntl_signal ( SIGTERM, "sig_handler" );
pcntl_signal ( SIGHUP, "sig_handler" );
// loop forever performing tasks
$bot = new IRC_BOT ( $config, $SER );
function sig_handler($signo) {
    switch ($signo) {
        case SIGTERM :
            $bot->machineKill();
            unlink($PID_FILE);
            exit ();
            break;
        case SIGHUP :
            $bot->machineKill();
            unlink($PID_FILE);
            break;
        default :

        // handle all other signals
    }
}

В зависимости от сервера, к которому я подключаюсь, поскольку он подключается максимум к 2 серверам, я запускаю в терминале следующее, чтобы запустить скрипт

php bot_start_shell.php --server="servernamehere" > /dev/null

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

1 Ответ

2 голосов
/ 06 августа 2011

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

Вот тестовый скрипт, который использует exit () для возврата значения в скрипт оболочки - 95,96 и 100 считаются другими «незапланированными перезапусками», обработанными в нижней части скрипта.

#!/usr/bin/php
<?php
// cli-script.php
// for testing of the BASH script
exit (rand(95, 100));

/* normally we would return one of
# 97  - planned pause/restart
# 98  - planned restart
# 99  - planned stop, exit.
# anything else is an unplanned restart
*/

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

#!/bin/bash

# runPHP-Worker.sh

# a shell script that keeps looping until an exit code is given
# if its does an exit(0), restart after a second - or if it's a declared error
# if we've restarted in a planned fashion, we don't bother with any pause
# and for one particular code, we can exit the script entirely.
# The numbers 97, 98, 99 must match what is returned from the PHP script

nice php -q -f ./cli-script.php -- $@
ERR=$?

## Possibilities
# 97    - planned pause/restart
# 98    - planned restart
# 99    - planned stop, exit.
# 0     - unplanned restart (as returned by "exit;")
#        - Anything else is also unplanned paused/restart

if [ $ERR -eq 97 ]
then
   # a planned pause, then restart
   echo "97: PLANNED_PAUSE - wait 1";
   sleep 1;
   exec $0 $@;
fi

if [ $ERR -eq 98 ]
then
   # a planned restart - instantly
   echo "98: PLANNED_RESTART, no pause";
   exec $0 $@;
fi

if [ $ERR -eq 99 ]
then
   # planned complete exit
   echo "99: PLANNED_SHUTDOWN";
   exit 0;
fi

# unplanned exit, pause, and then restart
echo "unplanned restart: err:" $ERR;
echo "sleeping for 1 sec"
sleep 1

exec $0 $@

Если вы нене хочу делать разные вещи для каждого значения, оно просто сводится к

#!/bin/bash
php -q -f ./cli-script.php -- $@
exec $0 $@;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...