Shell通过PHP:无法将新的cron作业添加到crontab

时间:2015-11-25 01:24:21

标签: php linux shell nginx cron

我有几个脚本计划在我的crontab中运行,但只能以root身份(或使用sudo)查看。我需要有一个PHP脚本(作为nginx运行)能够在crontab文件中添加一个新行。为此,我创建了一个shell脚本(由root拥有),并通过nginx文件向sudo用户授予/etc/sudoers权限。

/etc/sudoers文件的最后一行:

nginx ALL=NOPASSWD: /etc/nginx/addcron.sh

执行脚本的PHP调用:

chdir("/etc/nginx/");
echo exec("2>&1 ./addcron.sh $custname", $output);
echo "<pre>".print_r($output, true)."</pre>";

我目前的crontab:

[ec2-user@ip-172-31-xx-xxx nginx]$ sudo crontab -l
* * * * * env > /tmp/env.output
* * * * * /usr/bin/php -f /var/www/html/example/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/demo/cron/cron.php
0 23 * * * rm /tmp/cachegrind.out.*

关于我的addcron.sh文件的元信息:

[ec2-user@ip-172-31-xx-xxx nginx]$ pwd
/etc/nginx
[ec2-user@ip-172-31-xx-xxx nginx]$ ls -al addcron.sh
-rwxr-xr-x 1 root root 129 Nov 24 22:16 addcron.sh

addcron.sh的内容:

#!/bin/bash
custname="$1"
(crontab -l; echo \"* * * * * /usr/bin/php -f /var/www/html/$custname/cron/cron.php\" ) | crontab -

当我尝试运行时,我收到以下错误:

errors in crontab file, can't install.
Array
(
    [0] => "-":102: bad minute
    [1] => errors in crontab file, can't install.
)

似乎它不像-中的addcron.sh标记,但我的Google搜索建议这是正确的。另外,我尝试将sudo添加到PHP的exec命令中,但之后我收到以下错误:

sorry, you must have a tty to run sudo

我做错了什么或失踪了,为什么?

2 个答案:

答案 0 :(得分:1)

附注:在root帐户下运行与系统管理员无关的cron作业是来自安全角色的 BAD IDEA 。在nginx用户下安装你的crons。

问题是由你的bash脚本中的引号转义引起的(你可以直接在bash中检查,一块一块,顺便说一下):

> (crontab -l; echo \"* * * * * /usr/bin/php -f /var/www/html/$custname/cron/cron.php\" )
no crontab for username
"* ... <all kinds of filenames in here> ... /usr/bin/php -f /var/www/html/the_customer/cron/cron.php"

如果没有报价逃避的事情会更好一点:

> (crontab -l; echo "* * * * * /usr/bin/php -f /var/www/html/$custname/cron/cron.php" )
no crontab for username
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php

您可能希望添加一些防止重复条目的保护,这里是crontab在几次调用之后的样子:

> crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:10 2015)
# (Cronie version 4.2)
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:09 2015)
# (Cronie version 4.2)
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:09 2015)
# (Cronie version 4.2)
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:08 2015)
# (Cronie version 4.2)
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (- installed on Tue Nov 24 20:54:07 2015)
# (Cronie version 4.2)
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php
* * * * * /usr/bin/php -f /var/www/html/the_customer/cron/cron.php

答案 1 :(得分:0)

我最近发布了一个项目,允许PHP获取真正的Bash shell并与之交互。在此处获取:https://github.com/merlinthemagic/MTS

下载后,您只需使用以下代码:

$custname= "someone";
$strCmd = "echo \"* * * * * /usr/bin/php -f /var/www/html/".$custname."\" >> /cron/cron.php";

$shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1  = $shell->exeCmd($strCmd);
//assuming your distribution reloads / restarts using 'service'
$return2  = $shell->exeCmd('service crond restart');

这会将你的行附加到cron文件。