使用PHP创建,编辑和删除crontab作业?


115

是否可以使用PHP创建,编辑和删除crontab作业?

我知道如何列出Apache用户的当前crontab作业:

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

但是如何用PHP添加cron作业呢?'crontab -e'只会打开一个文本编辑器,您必须在保存文件之前手动编辑条目。

以及如何使用PHP删除cron作业?同样,您必须通过'crontab -e'手动执行此操作。

使用这样的作业字符串:

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

如何使用PHP将其添加到crontab作业列表中?



14
(提示) crontab只是一个文件
Gordon 2010年

1
@戈登,谢谢。我知道所有内容都是文件,但是它们在不同发行版的同一路径中存储crontab作业吗?另外,还需要获得Apache用户(例如www-data)并具有root特权?
datasn.io 2010年

我不确定路径是否会在发行版之间更改,但是您可以很好地在代码中将路径设置为可配置的值,然后在运行时进行设置。至于用户和权限:每个用户都可以拥有一个crontab,该crontab可以以分配给该用户的权限运行作业,因此这对于您的系统设置来说是独立的。
戈登

Answers:


132

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'是否会删除用户的所有作业?有什么方法可以删除用户的crontab中的特定作业行?加载,搜索然后删除找到的行似乎是唯一的方法。
datasn.io 2010年

3
您可以使用管道来代替编写临时文件
realmfoo'2

7
不错的解决方案,但shell_exec('crontab -l')只会返回最后一行。我用过exec('crontab -l', $output)。然后将$ output数组内嵌到字符串中(以\ n作为胶水)。
戴维·费尔班克斯

1
@Rahul如果服务器供应商没有提供像shell命令system()passthru()shell_exec()exec(),请尝试使用自带的主机,如的cPanel或的Plesk控制面板。
猛禽2014年

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 2012年

@Pacerier这个项目似乎已经死了并且有一些问题。尝试更活跃的yzalis / crontab
杰夫·普基特

10

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

函数append_cronjob对我不起作用。我得到的输出'-'不存在:数组([0] =>'-'不存在。[1] =>用法:crontab文件[2] => crontab [-e | -l | -r] [3] => -e(编辑用户的crontab)[4] => -l(列出用户的crontab)[5] => -r(删除用户的crontab))
user1307016 2015年

exec('echo -e“ crontab -l\ n'。$ command。'” | crontab-',$ output); 这是正确的吗。我没有www-data“-”:0的crontab:crontab文件中的分钟错误,无法安装。
Rahul Tailwal,2015年

Crontab用换行符(换行符)分隔作业。每个工作占用一行。因此,如果crontab在一行的第一列中看到的不是整数,则抛出“ bad minutes”错误,因为分钟参数是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

您可以将文件以cron格式放入/etc/cron.d/。在文件名中添加一些唯一的前缀要列出特定于脚本的cron作业,只需使用具有唯一前缀的文件列表即可。要禁用作业时,请删除文件。


我更喜欢此解决方案,因为它避免了操纵整个cron文件,并且易于删除,而不必在庞大的cron文件上添加和删除特定的cron任务。
Jovanni G

3

很好...
尝试删除特定的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>

请记住在exit;之后添加header('Location: ...');。而且,这种形式实际上非常危险,因为它可以添加cron作业来“破坏”服务器。
猛禽2014年

1
初学者注意:实际上,我们并没有在PHP标记中包装所有的PHP代码。PHP开头的一个,末尾的一个(可选)就足够了。
ekerner

0

最简单的方法是使用shell_exec命令执行bash脚本,并将值作为参数传递。从那里,您可以像在任何其他非交互式脚本中一样操作crontabs,还可以通过使用sudo等确保您具有正确的权限。

有关更多信息,请参见不带crontab -e的Crontab


某些人可能在共享主机中,因此这可能根本不起作用。
TheRealChx101 '17

-1

除了使用crontab之外,您还可以使用Google的应用引擎任务队列。它具有大量的免费配额,可快速,可扩展,可修改。


3
为什么不简单地使用cronjob?
和平者

-1

它很简单您可以卷曲来执行此操作,确保curl安装在服务器上:

触发每分钟:* * * * *卷曲--request POST ' https://glassdoor.com/admin/sendBdayNotification '

        • *

    分钟小时日月周

假设您想每天2:15 PM发送此通知, 您可以根据您的API更改POST / GET:

15 14 * * * curl --request POST'您的API的网址'

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.