Как запустить/остановить cronjob с помощью PHP?

Если я набираю crontab -l в командной строке, я вижу следующую строку:

# * * * * * /usr/bin/php /home/user/every_minute_script.php

Чтобы запустить этот cronjob, мне нужно отредактировать файл с помощью команды crontab -e, удалить символ комментария в начале строки, сохранить отредактированный файл и выйти из редактора.

Чтобы остановить эту cronjob, те же шаги, но добавив символ комментария в начале строки.

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

Ответ 1

Я провел некоторое исследование и найденное на форуме, следующее сообщение:

Вызвать "crontab -e" с помощью EDITOR переменная среды, установленная на php script. Этот script может изменять файла, и когда он выйдет из crontab, перечитайте файл и обновите его.

Итак, я что-то пробовал, и это сработало. Я вставлю рабочий код ниже:

#!/usr/bin/php
<?php

$on  = "* * * * * /usr/bin/php /home/user/every_minute_script.php\n";
$off = "# * * * * * /usr/bin/php /home/user/every_minute_script.php\n";

$param    = isset( $argv[1] ) ? $argv[1] : '';
$filename = isset( $argv[2] ) ? $argv[2] : '';

if ( $param == 'activate' )
{
    shell_exec( 'export EDITOR="/home/user/cron.php on"; crontab -e' );
}
elseif( $param == 'deactivate' )
{
    shell_exec( 'export EDITOR="/home/user/cron.php off"; crontab -e' );
}
elseif( in_array( $param, array( 'on', 'off' ) ) )
{
    if ( !is_writable( $filename ) )
        exit();

    $crontab = file( $filename );
    $key = array_search( $param == 'on' ? $off : $on, $crontab );

    if ( $key === false )
        exit();

    $crontab[$key] = $param == 'on' ? $on : $off;
    sleep( 1 );
    file_put_contents( $filename, implode( '', $crontab ) );
}

exit();

?>

Как бы то ни было, у нас есть один script с именем cron.php, расположенный в папке /home/user, установленный как исполняемый (chmod a+x cron.php) и вызываемый из командной строки (PHP-CLI). Позже я подберу его для запуска из Интернета, что является моим намерением.

Использование: ./cron.php activate, чтобы включить cronjob и ./cron.php deactivate, чтобы отключить его.

script правильно устанавливает переменную среды EDITOR (сам по себе), а затем вызывает crontab -e, который в свою очередь вызывает EDITOR (который теперь является тем же cron.PHP скрипт), который передает временное местоположение файла crontab как аргумент. Затем правильная строка crontab будет найдена и изменена, а измененная версия будет сохранена, заменив временный файл. Когда выйдет script, crontab будет обновляться.

Это делает именно то, что я хотел, и отвечал моим потребностям.

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

Ответ 2

Вместо того, чтобы программировать с помощью crontab (который является тонким и быстрым для гнева), я предлагаю сделать чек внутри your_minute_script.php:

if (!file_exists('/your/path/run_every_minute_script')) {
  exit;
}

Таким образом, script будет запускаться каждую минуту, но если условие не выполняется (/your/path/run_every_minute_script не существует), он немедленно прекратится без дальнейшей обработки.

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


Если вам нужен вывод, отправленный по почте, вы можете использовать обертку script. Crontab:

* * * * * /your/path/wrapper.sh > /dev/null 2> /dev/null

Затем оболочка script запускает соответствующее задание, собирает свой вывод и ошибки, а если они не пусты, отправляет их по почте (обратите внимание, что вы также можете сделать проверку внутри обертки script, мы didn ' t, поскольку он полагался на базу данных).

Ответ 3

Вот довольно классный учебник для создания именно такого рода функций с PHP.

Ответ 4

Установите условие остановки/запуска в начале every_minute_script.php

if($condition == false) {
    exit();
}

Ответ 5

Не могли бы вы поместить какую-то логику в начале every_minute_script.php, которая проверяет флаг, чтобы увидеть, нужно ли ему что-либо делать? Таким образом, он может разгоняться, а затем просто останавливаться, если нет работы.

Или это слишком неэффективно для ваших целей?