Перейти к содержимому


Фотография

что делать если cron нужен позарез, а платить не хочется


  • Закрытая тема Тема закрыта
В этой теме нет ответов

#1 OXOTHUK

OXOTHUK

    Участник

  • Пользователь
  • PipPip
  • 57 сообщений

Отправлено 26 Июнь 2011 - 10:46

подобная ситуация возникает когда вам, например, нужно чтобы psychostats собирал логи через ftp( например с нескольких серверов)

Решение этой проблеммы очень близко))


Cron средствами php


Для тех, кто не в курсе, cronTab, или “CronTable”, - это специальный инструмент, доступный на Linux, который облегчает планирование повторных задач, таким образом, освобождает нас от «обезьяньей работы».


Для того чтобы управлять cronTab при помощи PHP, мы будем нуждаться в возможности выполнять команды на удаленном сервере. К счастью, PHP предоставляет нам простой способ сделать - через библиотеку SSH2

Мы начнем наш класс с объявления четырёх приватных свойств:

$connection представляет наше подключение / ресурс;
$path представит путь для файла;
$handle представит название нашего временного cron файла;
$cron_file представляет полный путь и название временного cron файла;

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

После того, как пользователь авторизуется, ему понадобится метод, который будет связан с выполнением различных команд, точнее сказать ответственным за управление задачами. Мы назовем этот метод exec (). Данный метод мы будем вызывать из других методов нашего класса, когда нам понадобится выполнить команду на удаленном сервере.

Затем, нам понадобится возможность вписать cronTab в файл – на это у нас должны быть соответствующие права. Также не нужно забывать, что мы так же должны быть в состоянии удалить этот файл, когда он нам больше не будет нужен. Итак, к нашему методу прибавляется ещё несколько файлов, таких как write_to_file () и remove_file () для добавления и удаления файлов.

Конечно, мы будем также нуждаться в возможности создавать и удалять cron задачи. Таким образом, мы определим методы append_cronjob () и remove_cronjob ().

После того, как мы удалили единственный или последний cronjob, нам понадобится возможность удалить весь cronTab вместо того, чтобы пытаться создать пустой. Для этого мы напишем метод remove_crontab (), чтобы реализовать данную функциональность.

Наконец, мы создадим два вспомогательных метода для нашего класса. Один из них будет возвращать булево значение, проверяя существование временного cron файла. Второй будет использоваться для того, чтобы показать сообщения об ошибке, если таковое возникнет в ходе работы скрипта. Мы назовем эти методы crontab_file_exists () и error_message ().


<?php

            Class Ssh2_crontab_manager {

                        private $connection;
                        private $path;
                        private $handle;
                        private $cron_file;

                        function __construct() {...}

                        public function exec() {...}

                        public function write_to_file() {...}

                        public function remove_file() {...}

                        public function append_cronjob() {...}

                        public function remove_cronjob() {...}

                        public function remove_crontab() {...}

                        private function crontab_file_exists() {...}

                        private function error_message() {...}

            }


Конструктор класса прежде всего будет ответственен за установление и подтверждение связи SSH2. Для этого нам потребуется четыре аргумента, у каждого из которых будет значение по умолчанию NULL:

$host: представляет IP-адрес удаленного сервера, с которым мы хотим соединиться;
$port: порт, который будет использоваться для связи SSH2;
$username: пользователь, который пытается соединиться с сервером;
$password: пароль пользователя для сервера; function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL) {...}
Первое, что нам надо определить в пределах конструктора - это свойство $this->path, которое будет хранить полный путь по умолчанию для наших временных cron файлов.

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

Если значение данной константы нам недоступно, тогда путь нужно получить другим способом. Для этого мы можем воспользоваться функциями strrpos () и substr (), в которые будем передавать значение волшебной константы __FILE__, которая представит нам весь путь и название текущего файла.

Для того чтобы извлечь только путь, нам пригодится функция strrpos (), которая вернёт нам позицию слеша в значении __FILE__. Это значение, которое мы сохраним как $path_length, даст нам набор символов, не включая последний разделитель директорий.

После мы будем использовать функцию substr () для того, чтобы вырезать нужный нам фрагмент строки, а именно полный путь.

В substr () мы передадим 3 аргумента:

строку, с которой мы работаем;
начальную позицию, которая в нашем случае равна 0;
конечную позицию, которая хранится в переменной $path_length;
После выполнения данных функций у нас будет сформирован полный путь, в котором нуждается скрипт.

function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
{
    $path_length = strrpos(__FILE__, "/");
    $this->path  = substr(__FILE__, 0, $path_length) . '/';
}


Теперь мы определим строку, которая будет присваиваться по умолчанию для временного cron файла, а затем объединим с полным путём, который вычислили раньше. Вот мы и получили то, что нам нужно.


function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
{
    $path_length    = strrpos(__FILE__, "/");
    $this->path      = substr(__FILE__, 0, $path_length) . '/';
    $this->handle    = 'crontab.txt';
    $this->cron_file = "{$this->path}{$this->handle}";
}


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

В пределах этого блока мы сначала проверим, чтобы нам были доступны все аргументы. Для этого будем использовать функцию is_null (), которая возвращает истину или ложь. Если какой-либо из этих аргументов будет равен NULL, то мы выбросим новое исключение с соответствующим сообщением.

function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
{
    $path_length    = strrpos(__FILE__, "/");
    $this->path      = substr(__FILE__, 0, $path_length) . '/';
    $this->handle    = 'crontab.txt';
    $this->cron_file = "{$this->path}{$this->handle}";

    try
    {
        if (is_null($host) || is_null($port) || is_null($username) || is_null($password)) throw new Exception("Please specify the host, port, username and password!");
    }
    catch
    {

    }
}


Затем, мы определим $this->connection, передав аргументы $host и $port в функцию ssh2_connect () для того, чтобы установить соединение с сервером. Данный метод возвращает false, если соединение не было установлено.

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

function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
{
    $path_length    = strrpos(__FILE__, "/");
    $this->path      = substr(__FILE__, 0, $path_length) . '/';
    $this->handle    = 'crontab.txt';
    $this->cron_file = "{$this->path}{$this->handle}";

    try
    {
        if (is_null($host) || is_null($port) || is_null($username) || is_null($password)) throw new Exception("Please specify the host, port, username and password!");

        $this->connection = @ssh2_connect($host, $port);
        if ( ! $this->connection) throw new Exception("The SSH2 connection could not be established.");
    }
    catch
    {

    }
}


Теперь мы попытаемся определить подлинность пользователя, используя функцию ssh2_auth_password (), в которую предадим подключение, имя пользователя и его пароль. ssh2_auth_password () также возвращает булево значение, которое характеризует результат выполнения авторизации на сервере.

function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
{
    $path_length    = strrpos(__FILE__, "/");
    $this->path      = substr(__FILE__, 0, $path_length) . '/';
    $this->handle    = 'crontab.txt';
    $this->cron_file = "{$this->path}{$this->handle}";

    try
    {
        if (is_null($host) || is_null($port) || is_null($username) || is_null($password)) throw new Exception("Please specify the host, port, username and password!");

        $this->connection = @ssh2_connect($host, $port);
        if ( ! $this->connection) throw new Exception("The SSH2 connection could not be established.");

        $authentication = @ssh2_auth_password($this->connection, $username, $password);
        if ( ! $authentication) throw new Exception("Could not authenticate '{$username}' using password: '{$password}'.");
    }
    catch
    {

    }
}


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

Так, в блоке catch мы будем использовать метод getMessage, для того чтобы получить и показать сообщение, определенное в исключении.

Вы, наверное, уже поняли, что мы будем показывать исключения через метод error_message (), который определим чуть позже.
function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
{
    $path_length    = strrpos(__FILE__, "/");
    $this->path      = substr(__FILE__, 0, $path_length) . '/';
    $this->handle    = 'crontab.txt';
    $this->cron_file = "{$this->path}{$this->handle}";

    try
    {
        if (is_null($host) || is_null($port) || is_null($username) || is_null($password)) throw new Exception("Please specify the host, port, username and password!");

        $this->connection = @ssh2_connect($host, $port);
        if ( ! $this->connection) throw new Exception("The SSH2 connection could not be established.");

        $authentication = @ssh2_auth_password($this->connection, $username, $password);
        if ( ! $authentication) throw new Exception("Could not authenticate '{$username}' using password: '{$password}'.");
    }
    catch (Exception $e)
    {
        $this->error_message($e->getMessage());
    }
}



Выполнение множественных команд

Метод, который мы сейчас напишем, будет ответственен за выполнение команд на удаленном сервере. Это сопоставимо с ручным входом на сервер через программу PuTTY. Для того чтобы сохранить гибкую функциональность, мы сделаем методы публичными, чтобы пользователи могли выполнить любые команды, которые им необходимы для работы. Также мы сделаем возможным любое число аргументов. Эти аргументы представляют собой команды, которые будут запускаться функцией ssh2_exec ().

Итак, первая вещь, которую мы сделаем в этом методе, - это определим переменную, представляющую количество аргументов, которые передаются в метод. Мы будем использовать функцию PHP func_num_args(), для того чтобы получить это количество.

public function exec()
{
    $argument_count = func_num_args();
}

Теперь, в пределах блока try, мы проверим, передают ли какие-либо аргументы в этот метод или нет. Если количество аргументов будет равно 0, то мы бросим новое исключение с соответствующим сообщением.

public function exec()
{
    $argument_count = func_num_args();

    try
    {
        if ( ! $argument_count) throw new Exception("There is nothing to execute, no arguments specified.");
    }
    catch
    {

    }
}


Затем, используем функцию func_get_args () для создания множества всех аргументов, которые передали в этот метод.

Используя тернарный оператор, мы определим новую переменную, $command_string, как единую строку команды в Linux, которую будем выполнять.

Если у нас действительно будут множественные команды, то мы будем использовать функцию PHP, implode(), для того чтобы разобрать множество аргументов. В функцию implode() мы передаём два аргумента: строку и разделитель. Мы отделим каждый элемент разделителем &&, который позволит нам выполнять множественные команды, последовательно, на одной линии!

Если же будет введена только одна команда, то мы определим её как $arguments [0], который будет представлять первую и единственную команду.

public function exec()
{
    $argument_count = func_num_args();

    try
    {
        if ( ! $argument_count) throw new Exception("There is nothing to execute, no arguments specified.");

        $arguments = func_get_args();

        $command_string = ($argument_count > 1) ? implode(" && ", $arguments) : $arguments[0];

    }
    catch
    {

    }
}

Теперь, когда все подготовительные работы завершены, мы можем попытаться выполнить их, используя функцию ssh2_exec (). Мы передадим подключение $this->connection и строку команды $command_string. После этого метод ssh2_exe() возвратит результат.

И в этом случае, мы будем использовать блок try / catchдля того, чтобы иметь возможность отловить любые сообщения об ошибке. Также мы будем выбрасывать наше собственное исключение с соответствующим сообщением.

public function exec()
{
    $argument_count = func_num_args();

    try
    {
        if ( ! $argument_count) throw new Exception("There is nothing to execute, no arguments specified.");

        $arguments = func_get_args();

        $command_string = ($argument_count > 1) ? implode(" && ", $arguments) : $arguments[0];

        $stream = @ssh2_exec($this->connection, $command_string);
        if ( ! $stream) throw new Exception("Unable to execute the specified commands: {$command_string}");

    }
    catch
    {

    }
}


Вот именно для этого мы и написали блок try / catch! Теперь дополним это код вызовом метода error_message () для отображения ошибок!
public function exec()
{
    $argument_count = func_num_args();

    try
    {
        if ( ! $argument_count) throw new Exception("There is nothing to execute, no arguments specified.");

        $arguments = func_get_args();

        $command_string = ($argument_count > 1) ? implode(" && ", $arguments) : $arguments[0];

        $stream = @ssh2_exec($this->connection, $command_string);
        if ( ! $stream) throw new Exception("Unable to execute the specified commands: {$command_string}");

    }
    catch
    {
        $this->error_message($e->getMessage());
    }

    return $this;
}


Запись cronTabв файл

Следующий метод, write_to_file (), будет ответственен за запись cronTab во временный файл или создание нового файла. Для этого нам потребуется 2 аргумента:

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

public function write_to_file($path=NULL, $handle=NULL)
{
 
}

Первое, что мы здесь сделаем, так это проверим при помощи метода crontab_file_exists () существует ли cron файл. Если файл действительно существует, то создавать его не нужно. Если его нет, то мы будем использовать тернарный оператор, чтобы проверить наличие значений в переменных $path и $handle. Если хотя бы один из них будет равен NULL, то мы запустим процесс, который их определит.

После этого мы сольём данные в одно целое, которое будет содержать полный путь для временного cron файла.
public function write_to_file($path=NULL, $handle=NULL)
{
    if ( ! $this->crontab_file_exists())
    {
        $this->handle = (is_null($handle)) ? $this->handle : $handle;
        $this->path   = (is_null($path))   ? $this->path   : $path;

        $this->cron_file = "{$this->path}{$this->handle}";
    }
}

Затем мы будем использовать команду Linux crontab, с-l набором аргумента. Затем, используя Linux оператор >, мы перенаправим стандартный вывод, или STDOUT, в наш временный cron файл! Перенаправление вывода к файлу, используя оператор>, создаст файл, если он не существует.

public function write_to_file($path=NULL, $handle=NULL)
{
    if ( ! $this->crontab_file_exists())
    {
        $this->handle = (is_null($handle)) ? $this->handle : $handle;
        $this->path   = (is_null($path))   ? $this->path   : $path;

        $this->cron_file = "{$this->path}{$this->handle}";

        $init_cron = "crontab -l > {$this->cron_file}";
    }
}

Всё это работает очень хорошо в том случае, если у нас уже есть настроенные cronTab задачи. Если не будет никаких cron задач, то этот файл никогда не будет создаваться! Используя оператор &&, мы можем проверить несколько команд / выражений. Если файл не существует, то запустится содержание блока if.

public function write_to_file($path=NULL, $handle=NULL)
{
    if ( ! $this->crontab_file_exists())
    {
        $this->handle = (is_null($handle)) ? $this->handle : $handle;
        $this->path   = (is_null($path))   ? $this->path   : $path;

        $this->cron_file = "{$this->path}{$this->handle}";

        $init_cron = "crontab -l > {$this->cron_file} && [ -f {$this->cron_file} ] || > {$this->cron_file}";
    }
}

Наконец, мы вызовем метод exec () и передадим строку с командой.

public function write_to_file($path=NULL, $handle=NULL)
{
    if ( ! $this->crontab_file_exists())
    {
        $this->handle = (is_null($handle)) ? $this->handle : $handle;
        $this->path   = (is_null($path))   ? $this->path   : $path;

        $this->cron_file = "{$this->path}{$this->handle}";

        $init_cron = "crontab -l > {$this->cron_file} && [ -f {$this->cron_file} ] || > {$this->cron_file}";

        $this->exec($init_cron);
    }

    return $this;
}



Удаляем временный файл

Метод remove_file () прост настолько, насколько это может быть! Тут мы воспользуемся вспомогательным методом crontab_file_exists (), чтобы проверить существование временного cron файла и затем выполним команду Linux, чтобы удалить его. Как обычно мы также возвратим $this.

public function remove_file()
{
    if ($this->crontab_file_exists()) $this->exec("rm {$this->cron_file}");

    return $this;
}



Создание новой cron задачи


Метод, который мы сейчас напишем, будет создавать новую cron задачу. Метод append_cronjob () будет принимать один аргумент $cron_jobs, представляющий собой последовательность или множество последовательностей cron задач.

В самом начале этого метода мы проверим, является ли аргумент $cron_jobs равным NULL. Если да, то мы вызовем метод error_message(), чтобы остановить скрипт и показать пользователю сообщение об ошибке.

public function append_cronjob($cron_jobs=NULL)
{
    if (is_null($cron_jobs)) $this->error_message("Nothing to append!  Please specify a cron job or an array of cron jobs.");

}

Затем мы определим новую переменную $append_cronfile с текстом "echo", после которой стоит пробел и кавычка. Эту строку мы будем использовать для различных cron задач. Для конкатенации строк будем использовать выражение .=

Используя тернарный оператор, мы определим, содержит ли $cron_jobs множество команд. Если это будет так, то нам нужно разделить команды символом \n так, чтобы каждая cron задача располагалась на своей собственной строке. Если там только одно выражение, ничего из выше перечисленного мы не делаем.

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

public function append_cronjob($cron_jobs=NULL)
{
    if (is_null($cron_jobs)) $this->error_message("Nothing to append!  Please specify a cron job or an array of cron jobs.");

    $append_cronfile = "echo '";    

    $append_cronfile .= (is_array($cron_jobs)) ? implode("\n", $cron_jobs) : $cron_jobs;

    $append_cronfile .= "'  >> {$this->cron_file}";
 
}

Прежде чем выполнить команду через метод exec (), сначала необходимо вызвать метод write_to_file(), чтобы создать временный cron файл. После выполнения этих двух команд, следует вызвать remove_file(), чтобы удалить временный файл.

public function append_cronjob($cron_jobs=NULL)
{
    if (is_null($cron_jobs)) $this->error_message("Nothing to append!  Please specify a cron job or an array of cron jobs.");

    $append_cronfile = "echo '";                    

    $append_cronfile .= (is_array($cron_jobs)) ? implode("\n", $cron_jobs) : $cron_jobs;

    $append_cronfile .= "'  >> {$this->cron_file}";

    $install_cron = "crontab {$this->cron_file}";

    $this->write_to_file()->exec($append_cronfile, $install_cron)->remove_file();

    return $this;
}



Удаление существующих cron задач

Теперь, когда мы можем создать новые cron задачи, по логике вещей, нам необходимо иметь возможность их удалить! Метод remove_cronjob () будет принимать один аргумент, представляющий из себя регулярное выражением. Этот regEx будет использоваться для того, чтобы найти соответствие задачи в пределах cronTab и удалить их.

public function remove_cronjob($cron_jobs=NULL)
{
    if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

    $this->write_to_file();

}

Если cronTab не будет пуст, то тогда посчитаем элементы в $cron_array, используя функцию count(). Полученное значение сохраним в переменной $original_count.

public function remove_cronjob($cron_jobs=NULL)
{
    if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

    $this->write_to_file();

    $cron_array = file($this->cron_file, FILE_IGNORE_NEW_LINES);

    if (empty($cron_array)) $this->error_message("Nothing to remove!  The cronTab is already empty.");

    $original_count = count($cron_array);

}

Теперь у нас есть возможность узнать содержит ли $cron_jobs несколько значений или нет. Если да, то мы воспользуемся циклом foreach для обработки каждого значения. На каждом шаге будем использовать функцию preg_grep(). Эта изящная функция, мало чем отличается от preg_match(). В этом случае, однако, мы хотим получить элементы множества, которые не соответствуют шаблону. Таким образом, у нас будет множество всей cron работы, которой мы хотим сохранить!

public function remove_cronjob($cron_jobs=NULL)
{
    if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

    $this->write_to_file();

    $cron_array = file($this->cron_file, FILE_IGNORE_NEW_LINES);

    if (empty($cron_array)) $this->error_message("Nothing to remove!  The cronTab is already empty.");

    $original_count = count($cron_array);

    if (is_array($cron_jobs))
    {
        foreach ($cron_jobs as $cron_regex) $cron_array = preg_grep($cron_regex, $cron_array, PREG_GREP_INVERT);
    }
    else
    {

    }
}

Если аргументом $cron_jobs не будет множество, то мы продолжим двигаться в почти такой же манере, но без циклов.

public functionremove_cronjob($cron_jobs=NULL)
{
    if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

    $this->write_to_file();

    $cron_array = file($this->cron_file, FILE_IGNORE_NEW_LINES);

    if (empty($cron_array)) $this->error_message("Nothing to remove!  The cronTab is already empty.");

    $original_count = count($cron_array);

    if (is_array($cron_jobs))
    {
        foreach ($cron_jobs as $cron_regex) $cron_array = preg_grep($cron_regex, $cron_array, PREG_GREP_INVERT);
    }
    else
    {
        $cron_array = preg_grep($cron_jobs, $cron_array, PREG_GREP_INVERT);
    }
}

Далее мы сравним значение $cron_array с $original_count. Если длины будут идентичны, то мы просто вызовем метод remove_file(), чтобы удалить временный cron файл. Если они не будут соответствовать, то мы удалим существующий cronTab, а затем создадим новый!

public function remove_cronjob($cron_jobs=NULL)
{
    if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");

    $this->write_to_file();

    $cron_array = file($this->cron_file, FILE_IGNORE_NEW_LINES);

    if (empty($cron_array)) $this->error_message("Nothing to remove!  The cronTab is already empty.");

    $original_count = count($cron_array);

    if (is_array($cron_jobs))
    {
        foreach ($cron_jobs as $cron_regex) $cron_array = preg_grep($cron_regex, $cron_array, PREG_GREP_INVERT);
    }
    else
    {
        $cron_array = preg_grep($cron_jobs, $cron_array, PREG_GREP_INVERT);
    }           

    return ($original_count === count($cron_array)) ? $this->remove_file() : $this->remove_crontab()->append_cronjob($cron_array);
}



Удаление cronTab

Удаление всего cronTab сделать очень просто. По существу мы только выполним команду crontab -r, которая удалит весь cronTab для данного пользователя. Так как crontab был удален, мы могли бы также удалить временный cron файл.

public function remove_crontab()
{
    $this->exec("crontab -r")->remove_file();

    return $this;
}



Собираем всё в кучу

Теперь давайте посмотрим, как пользоваться созданным нами детищем:


Установка соединения

$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');

Создание одной задачи

$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');
$crontab->append_cronjob('30 8 * * 6 home/path/to/command/the_command.sh >/dev/null 2>&1');

Создание нескольких задач

$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');
$new_cronjobs = array(
                '0 0 1 * * home/path/to/command/the_command.sh',
                '30 8 * * 6 home/path/to/command/the_command.sh >/dev/null 2>&1'
);
 
$crontab->append_cronjob($new_cronjobs);

Удаление одной задачи

$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');
 
$cron_regex = '/home\/path\/to\/command\/the_command\.sh\/';
 
$crontab->remove_cronjob($cron_regex);

Удаление нескольких задач

$crontab = new Ssh2_crontab_manager('11.11.111.111', '22', 'my_username', 'my_password');
 
$cron_regex = array(
                '/0 0 1 \* \*/',
                '/home\/path\/to\/command\/the_command\.sh\/'
);
 
$crontab->remove_cronjob($cron_regex);




ну и напоследок пример собранного файла crontab средствами php


<?php

Class Ssh2_crontab_manager {

	private $connection;
	private $path;
	private $handle;
	private $cron_file;

	function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
	{		
		$path_length	 = strrpos(__FILE__, "/");
		$this->path 	 = substr(__FILE__, 0, $path_length) . '/';		
		$this->handle	 = 'crontab.txt';
		$this->cron_file = "{$this->path}{$this->handle}";
		
		try
		{
			if (is_null($host) || is_null($port) || is_null($username) || is_null($password)) throw new Exception("The host, port, username and password arguments must be specified!");
		
			$this->connection = @ssh2_connect($host, $port);			
			if ( ! $this->connection) throw new Exception("The SSH2 connection could not be established.");

			$authentication = @ssh2_auth_password($this->connection, $username, $password);
			if ( ! $authentication) throw new Exception("Could not authenticate '{$username}' using pasword: '{$password}'.");
		}
		catch (Exception $e)
		{
			$this->error_message($e->getMessage());
		}
	}

	public function exec()
	{
		$argument_count = func_num_args();

		try
		{
			if ( ! $argument_count) throw new Exception("There is nothing to exececute, no arguments specified.");

			$arguments = func_get_args();
			
			$command_string = ($argument_count > 1) ? implode(" && ", $arguments) : $arguments[0];
			
			$stream = @ssh2_exec($this->connection, $command_string);
			if ( ! $stream) throw new Exception("Unable to execute the specified commands: 
{$command_string}");
		}
		catch (Exception $e)
		{
			$this->error_message($e->getMessage());
		}

		return $this;
	}

	public function write_to_file($path=NULL, $handle=NULL)
	{
		if ( ! $this->crontab_file_exists())
		{		
			$this->handle = (is_null($handle)) ? $this->handle : $handle;
			$this->path   = (is_null($path))   ? $this->path   : $path;			
			$this->cron_file = "{$this->path}{$this->handle}";
			
			$init_cron = "crontab -l > {$this->cron_file} && [ -f {$this->cron_file} ] || > {$this->cron_file}";
			
			$this->exec($init_cron);		
		}
	
		return $this;	
	}
	
	public function remove_file()
	{		
		if ($this->crontab_file_exists()) $this->exec("rm {$this->cron_file}");		
		return $this;
	}
	
	public function append_cronjob($cron_jobs=NULL)
	{
		if (is_null($cron_jobs)) $this->error_message("Nothing to append!  Please specify a cron job or an array of cron jobs.");
		
		$append_cronfile = "echo '";		
		
		$append_cronfile .= (is_array($cron_jobs)) ? implode("\n", $cron_jobs) : $cron_jobs;
		
		$append_cronfile .= "'  >> {$this->cron_file}";
		
		$install_cron = "crontab {$this->cron_file}";

		$this->write_to_file()->exec($append_cronfile, $install_cron)->remove_file();
		
		return $this;		
	}
	
	public function remove_cronjob($cron_jobs=NULL)
	{	
		if (is_null($cron_jobs)) $this->error_message("Nothing to remove!  Please specify a cron job or an array of cron jobs.");
		
		$this->write_to_file();
	
		$cron_array = file($this->cron_file, FILE_IGNORE_NEW_LINES);
		
		if (empty($cron_array))
		{
			$this->remove_file()->error_message("Nothing to remove!  The cronTab is already empty.");			
		}
		
		$original_count = count($cron_array);
		
		if (is_array($cron_jobs))
		{
			foreach ($cron_jobs as $cron_regex) $cron_array = preg_grep($cron_regex, $cron_array, PREG_GREP_INVERT);
		}
		else
		{
			$cron_array = preg_grep($cron_jobs, $cron_array, PREG_GREP_INVERT);
		}
		
		return ($original_count === count($cron_array)) ? $this->remove_file() : $this->remove_crontab()->append_cronjob($cron_array);
	}

	public function remove_crontab()
	{
		$this->remove_file()->exec("crontab -r");		
		return $this;
	}

	private function crontab_file_exists()
	{
		return file_exists($this->cron_file);
	}
	
	private function error_message($error)
	{
		die("<pre style='color:#EE2711'>ERROR: {$error}</pre>");
	}
	
}

  • MrTrojan это нравится


Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных