Gunakan PHP untuk membuat, mengedit, dan menghapus pekerjaan crontab?

116

Apakah mungkin menggunakan PHP untuk membuat, mengedit, dan menghapus pekerjaan crontab?

Saya tahu cara membuat daftar pekerjaan crontab saat ini dari pengguna Apache:

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

Tetapi bagaimana cara menambahkan pekerjaan cron dengan PHP? 'crontab -e' hanya akan membuka editor teks dan Anda harus mengedit entri secara manual sebelum menyimpan file.

Dan bagaimana cara menghapus pekerjaan cron dengan PHP? Sekali lagi Anda harus melakukan ini secara manual dengan 'crontab -e'.

Dengan string pekerjaan seperti ini:

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

Bagaimana cara menambahkannya ke daftar pekerjaan crontab dengan PHP?

datasetn.io
sumber
2
kemungkinan duplikat dari pekerjaan Cron menggunakan php dan beberapa lainnya
Gordon
14
(petunjuk) crontab hanyalah sebuah file
Gordon
1
@Gordon, terima kasih. Saya tahu semuanya adalah file tetapi apakah mereka menyimpan pekerjaan crontab di jalur yang sama di distro yang berbeda? Plus itu perlu mendapatkan pengguna Apache, seperti www-data, dan memiliki hak akses root?
datasetn.io
Saya tidak yakin apakah jalur berubah di seluruh distro, tetapi Anda melakukannya dengan baik untuk membuat jalur menjadi nilai yang dapat dikonfigurasi dalam kode Anda dan mengaturnya saat runtime. Adapun pengguna dan izin: setiap pengguna dapat memiliki crontab yang menjalankan pekerjaan dengan hak yang diberikan kepada pengguna tersebut, jadi ini adalah individu untuk pengaturan sistem Anda.
Gordon

Jawaban:

133

penggunaan perintah 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)

Begitu,

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

Hal di atas dapat digunakan untuk membuat dan mengedit / menambahkan asalkan pengguna memiliki izin menulis file yang memadai.

Untuk menghapus pekerjaan:

echo exec('crontab -r');

Juga, perhatikan bahwa apache berjalan sebagai pengguna tertentu dan itu biasanya bukan root, yang berarti tugas cron hanya dapat diubah untuk pengguna apache kecuali diberikan crontab -uhak istimewa kepada pengguna apache.

ajreal
sumber
4
Bukankah 'crontab -r' akan menghapus semua pekerjaan pengguna? Apakah ada cara untuk menghapus baris pekerjaan tertentu di crontab pengguna? Memuat, mencari, dan kemudian menghapus baris yang ditemukan tampaknya menjadi satu-satunya cara.
datasetn.io
3
Anda dapat menggunakan pipa daripada menulis file sementara
realmfoo
7
Solusi bagus tetapi shell_exec('crontab -l')hanya akan mengembalikan baris terakhir. Saya dulu exec('crontab -l', $output). Kemudian implode array $ output menjadi string (dengan \ n sebagai perekatnya).
David Fairbanks
1
@Rahul jika penyedia server yang tidak memberikan perintah shell seperti system(), passthru(), shell_exec()dan exec(), coba menggunakan panel kontrol yang datang dengan hosting, seperti cPanel atau Plesk.
Raptor
3
ini akan terus menambahkan pekerjaan yang sama setiap kali dalam sebuah file. (dicentang) apakah ada cara untuk menghapus pekerjaan yang cocok terlebih dahulu lalu menulis yang baru?
RT
20

Kami baru-baru ini menyiapkan proyek mini (PHP> = 5.3) untuk mengelola file cron untuk tugas pribadi dan individu. Alat ini menghubungkan dan mengelola file cron sehingga Anda dapat menggunakannya, misalnya per proyek. Tes Unit tersedia :-)

Contoh dari baris perintah:

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

Contoh dari API:

use php\manager\crontab\CrontabManager;

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

Mengelola tugas individu dari 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

Chris Suszyński
sumber
Bagus. Ini pasti akan berguna ... dengan asumsi itu benar-benar berfungsi :)
Baraka
@Pacerier proyek ini tampaknya mati dan memiliki beberapa masalah. Coba yzalis / crontab yang lebih aktif.
Jeff Puckett
10

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

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

Hapus crontab

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

Contoh

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');
RafaSashi
sumber
function append_cronjob tidak bekerja untuk saya. Saya mendapatkan output '-' tidak ada: Array ([0] => '-' tidak ada. [1] => penggunaan: file crontab [2] => crontab [-e | -l | -r] [3] => -e (edit crontab pengguna) [4] => -l (crontab pengguna daftar) [5] => -r (hapus crontab pengguna))
user1307016
exec ('echo -e " crontab -l\ n'. $ command. '" | crontab -', $ output); Apakah itu benar. Saya tidak mendapatkan crontab untuk www-data "-": 0: kesalahan menit buruk dalam file crontab, tidak dapat menginstal.
Rahul Tailwal
Crontab membatasi pekerjaan dengan jeda baris (baris baru). Setiap pekerjaan menempati satu baris. Oleh karena itu, jika crontab melihat apa pun selain bilangan bulat di kolom pertama baris, crontab akan menampilkan kesalahan "menit buruk", karena argumen menit adalah pertemuan pertama crontab. lihat ini di dougv.com/2006/12/…
RafaSashi
terima kasih ... bagaimana saya bisa menggunakan cron_TZ menggunakan proyek Anda ??
Salem Ahmed
5

Ini harus dilakukan

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

Saya mencoba solusi di bawah ini

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

}

kredit untuk: Kelas Crontab untuk Menambah, Mengedit dan Menghapus Cron Jobs

Sam T
sumber
4

Anda dapat mencoba menimpa EDITORvariabel lingkungan dengan sesuatu seperti edyang dapat mengambil urutan perintah edit di atas input standar.

Alnitak
sumber
3

Tergantung di mana Anda menyimpan crontab Anda:

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

Anda dapat meletakkan file Anda ke /etc/cron.d/ dalam format cron. Tambahkan beberapa awalan unik ke nama file Untuk membuat daftar tugas cron khusus skrip, cukup gunakan daftar file dengan awalan unik. Hapus file jika Anda ingin menonaktifkan pekerjaan tersebut.

Dmitry Kireev
sumber
Saya lebih menyukai solusi ini karena menghindari manipulasi seluruh file cron dan mudah untuk dihapus vs harus menambah dan menghapus tugas cron tertentu pada file cron yang besar.
Jovanni G
3

Bagus ...
Coba ini untuk menghapus tugas cron tertentu (diuji).

<?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>
Ajie Kurniyawan
sumber
Ingatlah untuk menambahkan exit;setelah header('Location: ...');. Selain itu, formulir ini sebenarnya cukup berbahaya, karena dapat menambahkan tugas cron untuk "menghancurkan" server.
Raptor
1
Catatan untuk pemula: Kami sebenarnya tidak membungkus setiap baris PHP dalam tag PHP. Satu di awal PHP dan secara opsional satu di akhir sudah cukup.
ekerner
0

Cara termudah adalah dengan menggunakan perintah shell_exec untuk menjalankan skrip bash, dengan meneruskan nilai sebagai parameter. Dari sana, Anda dapat memanipulasi crontab seperti yang Anda lakukan di skrip non-interaktif lainnya, dan juga memastikan bahwa Anda memiliki izin yang benar dengan menggunakan sudo dll.

Lihat ini, Crontab tanpa crontab -e , untuk info lebih lanjut.

Codemwnci
sumber
Beberapa orang mungkin berada di host bersama jadi ini mungkin tidak berfungsi sama sekali.
TheRealChx101
-1

Selain crontab, Anda juga dapat menggunakan antrean tugas mesin aplikasi Google . Ini memiliki kuota gratis yang banyak, cepat, dapat diskalakan, dapat dimodifikasi.

Alfred
sumber
3
Mengapa tidak menggunakan cronjob saja?
Pacerier
-1

Sederhana saja Anda dapat menggulung untuk melakukannya, pastikan curl diinstal di server:

untuk memicu setiap menit: * * * * * curl --request POST ' https://glassdoor.com/admin/sendBdayNotification '

        • *

    menit jam hari bulan minggu

Katakanlah Anda ingin mengirim notifikasi ini 14:15 setiap hari Anda dapat mengubah POST / GET berdasarkan API Anda:

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

dinesh kandpal
sumber