【问题标题】:Shell via PHP: Trouble adding new cron job to crontabShell 通过 PHP:无法将新的 cron 作业添加到 crontab
【发布时间】:2015-11-25 01:24:20
【问题描述】:

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

/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 中的- 标记,但我的谷歌搜索表明这是正确的。另外,我尝试将sudo 添加到PHP 的exec 命令中,但随后出现以下错误:

sorry, you must have a tty to run sudo

我做错了什么或遗漏了什么,为什么?

【问题讨论】:

    标签: php linux shell nginx cron


    【解决方案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
    

    【讨论】:

    • 谢谢,我会考虑加强安全措施。删除引号消除了错误消息,但 crontab -e 仍然具有相同的内容,这很奇怪;我预计会出现错误或添加内容,但都没有发生。
    • 您是否正在检查 crontab 中的正确用户(调用脚本的用户或 root 如果在 sudo 下执行)?
    • 调用脚本的人是nginx,当我尝试对他们使用su,或者像他们一样运行命令时(runuser -l nginx -c 'crontab -l')我收到消息This account is currently not available.我正在尝试在root 下运行它,这就是为什么我将nginx ALL=NOPASSWD: /etc/nginx/addcron.sh 的位添加到/etc/sudoers,但sudo crontab -l 没有显示新条目,这就是为什么我很困惑,因为也没有错误消息。
    • 原来我没有收到任何错误消息的原因是因为它被添加了——只是给nginx用户,而不是root。我从来不知道如何改变它,但我也意识到我不需要或不想改变它,所以我很好。谢谢丹!
    【解决方案2】:

    我最近发布了一个项目,它允许 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 文件中。

    【讨论】:

      猜你喜欢
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-28
      • 1970-01-01
      • 2012-02-08
      • 2017-05-14
      • 2013-08-31
      • 1970-01-01
      相关资源
      最近更新 更多