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

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

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


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

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

使用类似这样的作业字符串:用PHP将其添加到crontab作业列表吗?

评论

使用php和其他几个程序可能会复制Cron作业

(提示)crontab只是一个文件

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

我不确定路径是否会在发行版之间更改,但是您可以很好地使路径在代码中成为可配置的值,然后在运行时进行设置。至于用户和权限:每个用户都可以拥有一个crontab,该crontab可以以分配给该用户的权限运行作业,因此这对于您的系统设置是独立的。
另请参阅stackoverflow.com/q/3186471/632951

#1 楼

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


以上内容可用于创建和编辑/如果用户具有足够的文件写入权限,则执行append。

要删除作业,请执行以下操作:

特定用户,并且通常不是root用户,这意味着cron作业只能为apache用户更改,除非为apache用户赋予了crontab -u特权。

评论


'crontab -r'是否会删除用户的所有作业?有什么方法可以删除用户的crontab中的特定作业行?加载,搜索然后删除找到的行似乎是唯一的方法。

–datasn.io
2010-12-12 11:26

您可以使用管道代替写入临时文件

– realmfoo
2012年2月3日在8:34

不错的解决方案,但shell_exec('crontab -l')仅返回最后一行。我使用了exec('crontab -l',$ output)。然后将$ output数组内嵌到字符串中(以\ n作为胶水)。

–大卫·费尔班克斯(David Fairbanks)
2012年12月23日的1:35

@Rahul如果服务器提供程序未提供诸如system(),passthru(),shell_exec()和exec()之类的shell命令,请尝试使用主机随附的控制面板,例如cPanel或Plesk。

–猛禽
2014年7月10日,下午3:15

每次将文件添加到同一作业。 (已选中)是否可以先删除匹配的作业,然后再编写新作业?

– R T
2014年12月17日上午8:03

#2 楼

我们最近准备了一个小型项目(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

评论


真好肯定会派上用场...假设它确实有效:)

–巴拉卡
2012年4月19日下午6:11

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

– Jeff Puckett
16年11月10日在21:07

#3 楼

检查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年1月5日在12:42



exec('echo -e“ crontab -l \ n'。$ command。'” | crontab-',$ output);这是对的吗。我没有www-data“-”:0的crontab:crontab文件中的严重错误,无法安装。

–拉胡尔·泰瓦尔(Rahul Tailwal)
15年1月31日,下午4:52

Crontab用换行符(换行符)分隔作业。每个工作占用一行。因此,如果crontab在一行的第一列中看到除整数以外的任何内容,则它将引发“糟糕的分钟”错误,因为分钟参数是crontab遇到的第一个参数。看看这个dougv.com/2006/12/…

– RafaSashi
15年1月31日在7:39

谢谢...我如何在您的项目中使用cron_TZ?

–塞勒姆·艾哈迈德(Salem Ahmed)
17年5月9日在6:01

#4 楼

这应该做到的

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作业

#6 楼

您可以尝试使用类似EDITOR的方法覆盖ed环境变量,该变量可以在标准输入上采用一系列编辑命令。

#7 楼

取决于crontab的存储位置:

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


#8 楼

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

评论


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

– Jovanni G
18年2月21日在4:43

#9 楼

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


评论


记住添加出口;在header('Location:...');之后。另外,这种形式实际上非常危险,因为它可以添加cron作业来“破坏”服务器。

–猛禽
2014年7月10日下午2:51

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

– ekerner
15年6月3日在16:43

#10 楼

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

请参阅此处,不带crontab -e的Crontab用于更多信息。

评论


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

–TheRealChx101
17年1月6日在21:14

#11 楼

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

评论


为什么不简单地使用cronjob?

–起搏器
2015年2月3日在16:27



#12 楼

它很简单您可以进行卷曲,确保将卷曲安装在服务器上:

每分钟触发一次:
* * * * * curl --request POST'https:// glassdoor .com / admin / sendBdayNotification'






*



/>分钟每小时一天每月一周


假设您要每天2:15 PM发送此通知
您可以根据自己的API更改POST / GET: >
15 14 * * * curl --request POST'ur API的网址'