Использовать PHP для создания, редактирования и удаления заданий crontab?

Можно ли использовать PHP для создания, редактирования и удаления заданий crontab?

Я знаю, как вывести список текущих заданий crontab пользователя Apache:

$output = shell_exec('crontab -l');
echo $output;

Но как добавить задание cron с помощью PHP? 'crontab -e' просто откроет текстовый редактор, и вам придется вручную отредактировать записи перед сохранением файла.

А как удалить задание cron с PHP? Опять же, вам нужно сделать это вручную с помощью crontab -e.

С такой строкой задания:

$job = '0 */2 * * * /usr/bin/php5 /home/user1/work.php';

Как мне добавить его в список заданий crontab с помощью PHP?


person datasn.io    schedule 12.12.2010    source источник
comment
возможный дубликат заданий Cron с использованием php и пара других   -  person Gordon    schedule 12.12.2010
comment
(подсказка) crontab - это просто файл   -  person Gordon    schedule 12.12.2010
comment
@ Гордон, спасибо. Я знаю, что все является файлом, но хранят ли они задания crontab по одному и тому же пути в разных дистрибутивах? Плюс нужно бы получить пользователя Apache, например www-data, и иметь привилегии root?   -  person datasn.io    schedule 12.12.2010
comment
Я не уверен, изменяется ли путь в разных дистрибутивах, но вы делаете все возможное, чтобы сделать путь настраиваемым значением в вашем коде и затем установить его во время выполнения. Что касается пользователя и разрешений: у каждого пользователя может быть crontab, который запускает задания с правами, назначенными этому пользователю, так что это индивидуально для настройки вашей системы.   -  person Gordon    schedule 12.12.2010
comment
См. Также stackoverflow.com/q/3186471/632951   -  person Pacerier    schedule 03.02.2015
comment
Попробуйте yzalis / crontab   -  person Jeff Puckett    schedule 11.11.2016


Ответы (12)


Использование команды crontab

usage:  crontab [-u user] file
        crontab [-u user] [ -e | -l | -r ]
                (default operation is replace, per 1003.2)
        -e      (edit user's crontab)
        -l      (list user's crontab)
        -r      (delete user's crontab)
        -i      (prompt before deleting user's crontab)

So,

$output = shell_exec('crontab -l');
file_put_contents('/tmp/crontab.txt', $output.'* * * * * NEW_CRON'.PHP_EOL);
echo exec('crontab /tmp/crontab.txt');

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

Чтобы удалить задания:

echo exec('crontab -r');

Также обратите внимание, что apache работает от имени конкретного пользователя, который обычно не является пользователем root, что означает, что задания cron могут быть изменены только для пользователя apache, если пользователю apache не предоставлено crontab -u привилегии.

person ajreal    schedule 12.12.2010
comment
Разве crontab -r не удалит все задания пользователя? Есть ли способ удалить определенную строку задания в crontab пользователя? Загрузка, поиск, а затем удаление найденной строки кажется единственным выходом. - person datasn.io; 12.12.2010
comment
Вы можете использовать каналы вместо записи временного файла - person realmfoo; 03.02.2012
comment
Хорошее решение, но shell_exec('crontab -l') вернет только последнюю строку. Я использовал exec('crontab -l', $output). Затем сверните массив $ output в строку (с \ n в качестве клея). - person David Fairbanks; 23.12.2012
comment
@ajreal, я сам добавил +1 к вашему комментарию как счастливый новичок в DO :), но потом я понял, что не все хотят работать (или нанимать) системного администратора в дополнение к своему обычному разработчику. задания. - person Sz.; 17.05.2014
comment
@Rahul, если поставщики серверов не предоставили такие команды оболочки, как system(), passthru(), shell_exec() и exec(), попробуйте использовать панель управления, которая поставляется с хостингом, например cPanel или Plesk. - person Raptor; 10.07.2014
comment
это будет продолжать добавлять одно и то же задание каждый раз в файл. (отмечено) есть ли способ сначала удалить совпадающие вакансии, а затем написать новую? - person R T; 17.12.2014
comment
Функции exec - это зло, большую часть времени вы не хотите, чтобы они работали на вашем веб-сервере - person Crasher; 05.12.2017
comment
Также это решение не работает, поскольку, как указано выше, оно не добавляет существующий контент. - person Crasher; 12.12.2017

Недавно мы подготовили мини-проект (PHP> = 5.3) для управления файлами cron для частных и индивидуальных задач. Этот инструмент соединяет файлы cron и управляет ими, чтобы вы могли использовать их, например, для каждого проекта. Доступны модульные тесты :-)

Пример из командной строки:

bin/cronman --enable /var/www/myproject/.cronfile --user www-data

Пример из API:

use php\manager\crontab\CrontabManager;

$crontab = new CrontabManager();
$crontab->enableOrUpdate('/tmp/my/crontab.txt');
$crontab->save();

Управление отдельными задачами из API:

use php\manager\crontab\CrontabManager;

$crontab = new CrontabManager();
$job = $crontab->newJob();
$job->on('* * * * *');
$job->onMinute('20-30')->doJob("echo foo");
$crontab->add($job);
$job->onMinute('35-40')->doJob("echo bar");
$crontab->add($job);
$crontab->save();

github: php-crontab-manager

person Chris Suszyński    schedule 11.04.2012
comment
Хороший. Это, безусловно, пригодится ... при условии, что это действительно работает :) - person Baraka; 19.04.2012
comment
@Pacerier, этот проект кажется мертвым и имеет некоторые проблемы. Попробуйте более активный yzalis / crontab. - person Jeff Puckett; 11.11.2016

Проверить cronjob

function cronjob_exists($command){

    $cronjob_exists=false;

    exec('crontab -l', $crontab);


    if(isset($crontab)&&is_array($crontab)){

        $crontab = array_flip($crontab);

        if(isset($crontab[$command])){

            $cronjob_exists=true;

        }

    }
    return $cronjob_exists;
}

Добавить cronjob

function append_cronjob($command){

    if(is_string($command)&&!empty($command)&&cronjob_exists($command)===FALSE){

        //add job to crontab
        exec('echo -e "`crontab -l`\n'.$command.'" | crontab -', $output);


    }

    return $output;
}

Удалить crontab

exec('crontab -r', $crontab);

Пример

exec('crontab -r', $crontab);

append_cronjob('* * * * * curl -s http://localhost/cron/test1.php');

append_cronjob('* * * * * curl -s http://localhost/cron/test2.php');

append_cronjob('* * * * * curl -s http://localhost/cron/test3.php');
person RafaSashi    schedule 14.07.2014
comment
функция append_cronjob у меня не работает. Я получаю вывод '-' не существует: массив ([0] = ›'-' не существует. [1] =› использование: crontab file [2] = ›crontab [-e | -l | -r] [3] = ›-e (редактировать crontab пользователя) [4] =› -l (выводить список crontab пользователя) [5] = ›-r (удалять crontab пользователя)) - person user1307016; 05.01.2015
comment
exec ('echo -e crontab -l \ n'. $ command. '| crontab -', $ output); это правильно. Я не получаю crontab для www-data -: 0: ошибки плохой минуты в файле crontab, не удается установить. - person Rahul Tailwal; 31.01.2015
comment
Crontab разделяет задания переносом строки (переводом строки). Каждое задание занимает одну строку. Следовательно, если crontab видит что-либо, кроме целого числа в первом столбце строки, он выдает ошибку «плохая минута», поскольку аргумент минуты является первым, с которым сталкивается crontab. проверьте это dougv.com/2006/12/ - person RafaSashi; 31.01.2015
comment
спасибо ... как я могу использовать cron_TZ в вашем проекте ?? - person Salem Ahmed; 09.05.2017

Это должно сделать это

shell_exec("crontab -l | { cat; echo '*/1    *    *    *    *    command'; } |crontab -");
person Fred    schedule 08.01.2013

Я попробовал решение ниже

class Crontab {

// In this class, array instead of string would be the standard input / output format.

// Legacy way to add a job:
// $output = shell_exec('(crontab -l; echo "'.$job.'") | crontab -');

static private function stringToArray($jobs = '') {
    $array = explode("\r\n", trim($jobs)); // trim() gets rid of the last \r\n
    foreach ($array as $key => $item) {
        if ($item == '') {
            unset($array[$key]);
        }
    }
    return $array;
}

static private function arrayToString($jobs = array()) {
    $string = implode("\r\n", $jobs);
    return $string;
}

static public function getJobs() {
    $output = shell_exec('crontab -l');
    return self::stringToArray($output);
}

static public function saveJobs($jobs = array()) {
    $output = shell_exec('echo "'.self::arrayToString($jobs).'" | crontab -');
    return $output; 
}

static public function doesJobExist($job = '') {
    $jobs = self::getJobs();
    if (in_array($job, $jobs)) {
        return true;
    } else {
        return false;
    }
}

static public function addJob($job = '') {
    if (self::doesJobExist($job)) {
        return false;
    } else {
        $jobs = self::getJobs();
        $jobs[] = $job;
        return self::saveJobs($jobs);
    }
}

static public function removeJob($job = '') {
    if (self::doesJobExist($job)) {
        $jobs = self::getJobs();
        unset($jobs[array_search($job, $jobs)]);
        return self::saveJobs($jobs);
    } else {
        return false;
    }
}

}

кредиты для: Класс Crontab для добавления, редактирования и удаления заданий Cron

person Sam Arul Raj T    schedule 03.03.2016

Вы можете попробовать переопределить переменную среды EDITOR чем-то вроде ed, которое может принимать последовательность команд редактирования вместо стандартного ввода.

person Alnitak    schedule 12.12.2010

Зависит от того, где вы храните crontab:

shell_exec('echo "'. $job .'" >> crontab');
person thedom    schedule 12.12.2010

Вы можете поместить свой файл в /etc/cron.d/ в формате cron. Добавьте уникальный префикс к имени файла. Чтобы вывести список заданий cron, специфичных для сценария, просто поработайте со списком файлов с уникальным префиксом. Удалите файл, если хотите отключить задание.

person Dmitry Kireev    schedule 07.01.2012
comment
Мне больше нравится это решение, потому что оно позволяет избежать манипуляций со всем файлом cron и его легко удалить, а не добавлять и удалять конкретную задачу cron в огромном файле cron. - person Jovanni G; 21.02.2018

Хорошо ...
Попробуйте удалить конкретное задание cron (проверено).

<?php $output = shell_exec('crontab -l'); ?>
<?php $cron_file = "/tmp/crontab.txt"; ?>

<!-- Execute script when form is submitted -->
<?php if(isset($_POST['add_cron'])) { ?>

<!-- Add new cron job -->
<?php if(!empty($_POST['add_cron'])) { ?>
<?php file_put_contents($cron_file, $output.$_POST['add_cron'].PHP_EOL); ?>
<?php } ?>

<!-- Remove cron job -->
<?php if(!empty($_POST['remove_cron'])) { ?>
<?php $remove_cron = str_replace($_POST['remove_cron']."\n", "", $output); ?>
<?php file_put_contents($cron_file, $remove_cron.PHP_EOL); ?>
<?php } ?>

<!-- Remove all cron jobs -->
<?php if(isset($_POST['remove_all_cron'])) { ?>
<?php echo exec("crontab -r"); ?>
<?php } else { ?>
<?php echo exec("crontab $cron_file"); ?>
<?php } ?>

<!-- Reload page to get updated cron jobs -->
<?php $uri = $_SERVER['REQUEST_URI']; ?>
<?php header("Location: $uri"); ?>
<?php exit; ?>
<?php } ?>

<b>Current Cron Jobs:</b><br>
<?php echo nl2br($output); ?>

<h2>Add or Remove Cron Job</h2>
<form method="post" action="<?php $_SERVER['REQUEST_URI']; ?>">
<b>Add New Cron Job:</b><br>
<input type="text" name="add_cron" size="100" placeholder="e.g.: * * * * * /usr/local/bin/php -q /home/username/public_html/my_cron.php"><br>
<b>Remove Cron Job:</b><br>
<input type="text" name="remove_cron" size="100" placeholder="e.g.: * * * * * /usr/local/bin/php -q /home/username/public_html/my_cron.php"><br>
<input type="checkbox" name="remove_all_cron" value="1"> Remove all cron jobs?<br>
<input type="submit"><br>
</form>
person Ajie Kurniyawan    schedule 24.01.2014
comment
Не забудьте добавить exit; после header('Location: ...');. Кроме того, эта форма на самом деле довольно опасна, так как может добавить задание cron для уничтожения сервера. - person Raptor; 10.07.2014
comment
Примечание для новичков: на самом деле мы не заключаем каждую строку PHP в теги PHP. Достаточно одного в начале PHP и, возможно, в конце. - person ekerner; 03.06.2015

Самый простой способ - использовать команду shell_exec для выполнения сценария bash, передавая значения в качестве параметров. Оттуда вы можете управлять crontab, как и в любом другом неинтерактивном скрипте, а также убедиться, что у вас есть правильные разрешения, используя sudo и т. Д.

См. Crontab без crontab -e для получения дополнительной информации.

person Codemwnci    schedule 12.12.2010
comment
Некоторые люди могут находиться на общем хосте, поэтому это может вообще не работать. - person TheRealChx101; 07.01.2017

Это просто. Вы можете сделать это с помощью curl, убедитесь, что на сервере установлен curl:

для запуска каждую минуту: * * * * * curl --request POST 'https://glassdoor.com/admin/sendBdayNotification '

        • *

    минута час день месяц неделя

Допустим, вы хотите отправлять это уведомление в 14:15 каждый день Вы можете изменить POST / GET в зависимости от вашего API:

15 14 * * * curl --request POST 'url ur API'

person dinesh kandpal    schedule 22.03.2018

Вместо crontab вы также можете использовать движок приложений Google очередь задач. У него большая бесплатная квота, он быстрый, масштабируемый и модифицируемый.

person Alfred    schedule 12.12.2010
comment
Почему бы просто не использовать cronjob? - person Pacerier; 03.02.2015