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


116

Чи можна використовувати PHP для створення, редагування та видалення завдань 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?


2
можливий дублікат завдань Cron, використовуючи php та пару інших
Гордон

14
(натяк) crontab - це лише файл
Гордон

1
@Gordon, спасибі Я знаю, що все є файлом, але чи вони зберігають завдання crontab на одному шляху по різних дистрибутивах? Плюс потрібно було б отримати користувача Apache, наприклад www-data, і мати привілеї root?
datasn.io

Я не впевнений, чи зміниться шлях через дистрибутив, але ви робите добре, щоб зробити шлях, який можна настроювати у своєму коді, і встановити його під час виконання. Що стосується користувача та дозволів: кожен користувач може мати crontab, який виконує завдання з правами, призначеними цьому користувачеві, тож це індивідуально для налаштування вашої системи.
Гордон

Відповіді:


133

використання команд 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)

Так,

$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пільги.


4
Чи не "crontab -r" видалить усі завдання користувача? Чи є якийсь спосіб видалити певну лінію завдання з кронтових запитів користувача? Здається, завантаження, пошук та видалення знайденої лінії є єдиним способом.
datasn.io

3
Ви можете використовувати труби замість того, щоб писати тимчасовий файл
realmfoo

7
Приємне рішення, але shell_exec('crontab -l')поверне лише останній рядок. Я звик exec('crontab -l', $output). Потім імплантуйте вивідний масив $ у рядок (з \ n як клей).
Девід Фербенкс

1
@Rahul якщо постачальники сервера не забезпечують оболонки команди , як system(), passthru(), shell_exec()і exec(), спробуйте з допомогою панелі управління , яка поставляється з хостингом, такі як CPanel або Plesk.
Раптор

3
це продовжує додавати одне і те ж завдання кожен раз у файл. (перевірено) чи є спосіб спочатку видалити відповідні завдання, а потім написати нове?
RT

20

Нещодавно ми підготували міні-проект (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


Приємно. Це, безумовно, стане в нагоді ... якщо припустити, що це насправді працює :)
Baraka

@Pacerier Цей проект здається мертвим і має деякі проблеми. Спробуйте yzalis / crontab, який є більш активним.
Джефф Пукетт

10

Перевірте кронштейн

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;
}

Додайте кронштейн

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;
}

Видаліть кронтаб

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');

функція append_cronjob не працює для мене. Я отримую вихід '-' не існує: Array ([0] => '-' не існує. [1] => використання: файл crontab [2] => crontab [-e | -l | -r] [3] => -e (редагувати crontab користувача) [4] => -l (список користувачів crontab) [5] => -r (видалити crontab користувача))
користувач1307016

exec ('echo -e " crontab -l\ n'. $ command. '" | crontab -', $ output); це правильно. Я не отримую crontab для www-data "-": 0: погані хвилинні помилки у файлі crontab, не можу встановити.
Rahul Tailwal

Crontab розмежовує завдання за допомогою перерв рядків (нових рядків). Кожна робота займає один рядок. Отже, якщо crontab бачить що-небудь, крім цілого числа, у першому стовпці рядка, він видає помилку "поганої хвилини", оскільки аргумент хвилини є першим, на якому зіштовхується crontab. перевірити це dougv.com/2006/12/…
RafaSashi

дякую ... як я можу використовувати cron_TZ за допомогою вашого проекту ??
Салем Ахмед

5

Це має робити

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

5

Я спробував рішення нижче

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


4

Ви можете спробувати змінити EDITORзмінну оточуючого середовища на щось подібне, edщо може приймати послідовність команд редагування над стандартним входом.


3

Залежить, де ви зберігаєте свій crontab:

shell_exec('echo "'. $job .'" >> crontab');

3

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


Мені подобається це рішення краще, тому що воно дозволяє уникнути маніпулювання всім файлом cron, і його легко видалити проти необхідності додавання та видалення конкретної задачі cron у величезному файлі cron.
Jovanni G

3

Приємно ...
Спробуйте це видалити конкретну роботу з крон (перевірено).

<?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>

Не забудьте додати exit;після header('Location: ...');. Також ця форма насправді є досить небезпечною, оскільки може додати роботу cron для "знищення" сервера.
Раптор

1
Примітка для початківців: Насправді ми не обертаємо кожен рядок PHP тегами PHP. Одного на початку PHP і, можливо, одного в кінці буде достатньо.
екернер

0

Найпростіший спосіб - використовувати команду shell_exec для виконання сценарію bash, передаючи значення як параметри. Звідти ви можете маніпулювати кронтами, як у будь-якому іншому неінтерактивному сценарії, а також гарантувати правильність дозволів за допомогою sudo тощо.

Дивіться це, Crontab без crontab -e , для отримання додаткової інформації.


Деякі люди можуть перебувати у спільному хості, тому це може не працювати взагалі.
TheRealChx101

-1

Замість crontab ви також можете використовувати чергу завдань двигуна програми Google . Він має щедру безкоштовну квоту, швидко, масштабується, змінюється.


3
Чому б просто не використовувати cronjob?
Pacerier

-1

Її просте Ви можете зробити його завитками, переконайтесь, що curl встановлений на сервері:

для запуску щохвилини: * * * * * curl - запит POST ' https://glassdoor.com/admin/sendBdayNotification '

        • *

    хвилинна година день місяць тиждень

Скажімо, ви хочете надсилати це повідомлення щоразу 14:15. Ви можете змінювати POST / GET на основі свого API:

15 14 * * * curl - запит POST 'url ur ur API'

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.