【问题标题】:Cannot run shell_exec in cron'd PHP, $PATH is not visible as well无法在 cron'd PHP 中运行 shell_exec,$PATH 也不可见
【发布时间】:2013-11-06 11:52:35
【问题描述】:

我正在尝试在我们的环境中实施测试集成解决方案。简单的工作流程是这样的:我在 AWS 中有一个 CentOS EC2 实例,其中有一个 MySQL 数据库,其中的行代表要运行的测试(每个都有唯一的 id、绝对文件路径、开始时间、完成时间等)。这些测试实际上是 python 脚本(使用 unittest 框架)。

我创建了一个 PHP 脚本(我选择的语言),它从数据库中获取所有未启动的测试,并使用 python 甚至 py.test 在本地运行它们,我在代码中通过shell_exec() 执行。

不过,在运行 PHP 脚本之前,我还执行(至少是第一次)以下 bash 脚本,以使用带有 WebDriver、Selenium Server 和 Xvfb 的无头 Firefox 设置本地测试环境以进行“显示”:

#!/bin/bash

if [ `whoami` != "root" ] ; then
        echo "Run as root!"
        exit 1
fi

#Start X virtual frame buffer
/etc/init.d/xvfb start

#Add fake display to env
export DISPLAY=:99

#Start Selenium Server
java -jar /opt/selenium-server/selenium-server-standalone-2.33.0.jar &

如果我像这样从终端运行我的 PHP 脚本:# php script.php 一切运行正常,php 调用 shell_exec() 依次运行 python 以使用假显示等通过 py.test 执行测试。

但是,当我尝试将此 PHP 脚本添加到 cron 作业中时,它会失败。我的 cron.d 文件如下所示:

* * * * * root /usr/bin/php /path/to/script.php >> /path/to/log.log

我在网上看到一个解决方案是创建一个 shell 脚本,该脚本将调用其中的 PHP 脚本并将其放入 cron 中。我试过了,它似乎做了一些事情,但它卡在了另一个地方(首先在我的 shell 脚本中,我有 export DISPLAY=:99 以防万一,所以 python 脚本会看到虚拟显示,但我不确定是否需要) .

无论如何,按照上面的方法,py.test 以某种方式执行,但是当它尝试定位 Firefox 二进制文件(位于 /usr/local/bin/firefox)时会引发异常。似乎 shell 脚本看不到 $PATH。但我也读过以下内容:一个在其中执行另一个脚本(在我们的例子中是 PHP)的 shell 脚本实际上为此产生了一个孩子,所以即使在父脚本上设置了这个孩子也不一定能看到 $PATH ?我不确定。

你能帮帮我吗?在 cron 中运行上述所有内容的最佳方法是什么? 如何让 PHP 或 shell 脚本看到 $PATH? (如果至少是这样的话)

【问题讨论】:

    标签: php python shell cron shell-exec


    【解决方案1】:

    您可以在 cron 命令的开头导出 PATH

    找到正确的路径

    $) echo $PATH
    /some/path:/some/other/path
    

    在你的 crontab 中,写

    * * * * * export PATH="/some/path:/some/other/path" && /usr/bin/php /path/to/script.php >> /path/to/log.log
    

    或者,您可以在 crontab 文件的开头设置它以及显示here

    由于您正在设置DISPLAY 环境变量的值并启动xvfb 服务器,因此您应该考虑在您的shell 脚本中设置路径并将shell 脚本作为cron 作业(而不是php我在示例中使用的脚本)

    【讨论】:

    • 谢谢@ansh0l,这成功了!我不确定我是否需要 shell 脚本并设置 DISPLAY 环境变量,因为 Xvfb 似乎创建了一个带有另一个 ID 的“新”屏幕。
    • 酷!这只是一个建议,以防您想继续使用 shell 脚本而不是 php 脚本。
    【解决方案2】:

    从 root 用户创建一个 crontab 作业并从 * * * * * root /usr/bin/php /path/to/script.php >> /path/to/log.log 中删除 root

    【讨论】:

    • 您好,我尝试了 ansh0l 的上述解决方案并且效果很好,但我很好奇您写的内容。 root 的 crontab 与将 root 指定为在其帐户下运行脚本的用户的常规 cron 有区别吗?
    • 让我先问一个问题,如果您从其他用户运行 crontab 作业,它如何知道 root 密码?
    • 如果你以 root 身份运行它,你可以省略 root 这个词。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    相关资源
    最近更新 更多