Sử dụng PHP để tạo, chỉnh sửa và xóa các công việc crontab?


116

Có thể sử dụng PHP để tạo, chỉnh sửa và xóa các công việc crontab không?

Tôi biết cách liệt kê các công việc crontab hiện tại của người dùng Apache:

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

Nhưng làm thế nào để thêm một công việc cron với PHP? 'crontab -e' sẽ chỉ mở một trình soạn thảo văn bản và bạn sẽ phải chỉnh sửa thủ công các mục nhập trước khi lưu tệp.

Và làm cách nào để xóa cron job bằng PHP? Một lần nữa bạn phải làm điều này theo cách thủ công bằng 'crontab -e'.

Với một chuỗi công việc như thế này:

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

Làm cách nào để thêm nó vào danh sách việc làm crontab bằng PHP?



14
(gợi ý) crontab chỉ là một tệp
Gordon

1
@Gordon, cảm ơn. Tôi biết mọi thứ đều là một tệp nhưng họ có đang lưu trữ các công việc crontab tại cùng một đường dẫn trên các bản phân phối khác nhau không? Thêm vào đó, nó sẽ cần phải có được người dùng của Apache, chẳng hạn như www-data, và có các đặc quyền của root?
datasn.io

Tôi không chắc liệu đường dẫn có thay đổi trên các bản phân phối hay không, nhưng bạn đang làm tốt để đặt đường dẫn thành một giá trị có thể định cấu hình trong mã của bạn và đặt nó trong thời gian chạy. Đối với người dùng và quyền: mọi người dùng đều có thể có crontab chạy các công việc với các quyền được chỉ định cho người dùng đó, vì vậy đây là cá nhân cho thiết lập hệ thống của bạn.
Gordon

Câu trả lời:


133

sử dụng lệnh 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)

Vì thế,

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

Ở trên có thể được sử dụng cho cả tạo và chỉnh sửa / nối thêm miễn là người dùng có đủ quyền ghi tệp.

Để xóa công việc:

echo exec('crontab -r');

Ngoài ra, hãy lưu ý rằng apache đang chạy với tư cách là một người dùng cụ thể và đó thường không phải là root, có nghĩa là các công việc cron chỉ có thể được thay đổi cho người dùng apache trừ khi được cấp crontab -uđặc quyền cho người dùng apache.


4
'Crontab -r' sẽ không xóa tất cả các công việc của người dùng? Có cách nào để xóa một dòng công việc cụ thể trong crontabs của người dùng không? Tải, tìm kiếm và sau đó xóa dòng tìm thấy dường như là cách duy nhất.
datasn.io

3
Bạn có thể sử dụng ống thay vì viết một tập tin tạm thời
realmfoo

7
Giải pháp tốt nhưng shell_exec('crontab -l')sẽ chỉ trả lại dòng cuối cùng. Tôi đã sử dụng exec('crontab -l', $output). Sau đó, mã hóa mảng đầu ra $ thành một chuỗi (với \ n là chất kết dính).
David Fairbanks

1
@Rahul nếu các nhà cung cấp máy chủ đã không cung cấp các lệnh shell như system(), passthru(), shell_exec()exec(), hãy thử sử dụng bảng điều khiển đi kèm với hosting, chẳng hạn như cPanel hoặc Plesk.
Raptor

3
điều này sẽ tiếp tục bổ sung cùng một công việc mỗi lần trong một tệp. (đã chọn) có cách nào để xóa các công việc phù hợp trước rồi viết một công việc mới không?
RT

20

Gần đây, chúng tôi đã chuẩn bị một dự án nhỏ (PHP> = 5.3) để quản lý các tệp cron cho các tác vụ riêng tư và cá nhân. Công cụ này kết nối và quản lý các tệp cron để bạn có thể sử dụng chúng, chẳng hạn như cho mỗi dự án. Kiểm tra đơn vị có sẵn :-)

Mẫu từ dòng lệnh:

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

Mẫu từ API:

use php\manager\crontab\CrontabManager;

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

Quản lý các tác vụ riêng lẻ từ 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


Đẹp. Điều này chắc chắn sẽ có ích ... giả sử nó thực sự hoạt động :)
Baraka

@Pacerier dự án này có vẻ đã chết và có một số vấn đề. Hãy thử yzalis / crontab hoạt động nhiều hơn.
Jeff Puckett

10

Kiểm tra một 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;
}

Nối một 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;
}

Xóa crontab

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

Thí dụ

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

function append_cronjob không hoạt động với tôi. Tôi nhận được kết quả đầu ra '-' không tồn tại: Array ([0] => '-' không tồn tại. [1] => cách sử dụng: tệp crontab [2] => crontab [-e | -l | -r] [3] => -e (chỉnh sửa crontab của người dùng) [4] => -l (danh sách crontab của người dùng) [5] => -r (xóa crontab của người dùng))
user1307016

execute ('echo -e " crontab -l\ n'. $ command. '" | crontab -', $ output); nó có đúng không. Tôi không nhận được crontab cho www-data "-": 0: lỗi phút tồi tệ trong tệp crontab, không thể cài đặt.
Rahul Tailwal

Crontab phân định các công việc bằng ngắt dòng (dòng mới). Mỗi công việc chiếm một dòng. Do đó, nếu crontab nhìn thấy bất kỳ thứ gì khác ngoài một số nguyên trong cột đầu tiên của một dòng, nó sẽ ném ra lỗi "bad minutes", vì đối số phút là đối số đầu tiên mà crontab gặp phải. kiểm tra cái này trên dougv.com/2006/12/…
RafaSashi,

cảm ơn ... làm thế nào tôi có thể sử dụng cron_TZ bằng cách sử dụng dự án của bạn ??
Salem Ahmed

5

Điều này nên làm điều đó

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

5

Tôi đã thử giải pháp bên dưới

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

}

tín dụng cho: Lớp Crontab để Thêm, Chỉnh sửa và Xóa Công việc Cron


4

Bạn có thể thử ghi đè EDITORbiến môi trường bằng một cái gì đó tương tự như edvậy có thể thực hiện một chuỗi các lệnh chỉnh sửa qua đầu vào chuẩn.


3

Phụ thuộc vào nơi bạn lưu trữ crontab của mình:

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

3

Bạn có thể đặt tệp của mình thành /etc/cron.d/ ở định dạng cron. Thêm một số tiền tố duy nhất vào tên tệp Để liệt kê các công việc cron dành riêng cho tập lệnh, chỉ cần làm việc với danh sách các tệp có tiền tố duy nhất. Xóa tệp khi bạn muốn vô hiệu hóa công việc.


Tôi thích giải pháp này hơn vì nó tránh thao tác toàn bộ tệp cron và dễ dàng loại bỏ so với việc phải thêm và xóa một tác vụ cron cụ thể trên một tệp cron lớn.
Jovanni G

3

Tốt ...
Hãy thử điều này để xóa một công việc cron cụ thể (đã thử nghiệm).

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

Nhớ thêm exit;vào sau header('Location: ...');. Ngoài ra, hình thức này thực sự khá nguy hiểm, vì nó có thể thêm công việc cron để "phá hủy" máy chủ.
Raptor

1
Lưu ý cho người mới bắt đầu: Chúng tôi không thực sự gói mọi dòng PHP trong các thẻ PHP. Một ở đầu PHP và tùy chọn ở cuối là đủ.
ekerner

0

Cách dễ nhất là sử dụng lệnh shell_exec để thực thi một tập lệnh bash, chuyển các giá trị dưới dạng tham số. Từ đó, bạn có thể thao tác crontabs giống như bạn làm trong bất kỳ tập lệnh không tương tác nào khác và cũng đảm bảo rằng bạn có quyền chính xác bằng cách sử dụng sudo, v.v.

Xem này, Crontab mà không có crontab -e , để biết thêm thông tin.


Một số người có thể đang ở trong một máy chủ được chia sẻ nên điều này có thể không hoạt động.
TheRealChx101

-1

Thay vì crontab, bạn cũng có thể sử dụng hàng đợi công cụ ứng dụng của google . Nó có một hạn ngạch miễn phí rộng rãi, nhanh chóng, có thể mở rộng, có thể sửa đổi.


3
Tại sao không chỉ đơn giản là sử dụng cronjob?
Pacerier

-1

Nó đơn giản Bạn có thể cuộn để làm như vậy, hãy đảm bảo curl được cài đặt trên máy chủ:

để kích hoạt mỗi phút: * * * * * curl --yêu cầu BÀI ĐĂNG ' https://glassdoor.com/admin/sendBdayNotification '

        • *

    phút giờ ngày tháng tuần

Giả sử bạn muốn gửi thông báo này lúc 2:15 chiều hàng ngày Bạn có thể thay đổi POST / GET dựa trên API của mình:

15 14 * * * curl --yêu cầu POST 'url của API của bạn'

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.