【问题标题】:PHP system() call doesn't work when called by shell由shell调用时PHP system()调用不起作用
【发布时间】:2023-03-14 03:11:01
【问题描述】:

我有一个由 cron 运行的 shell 文件:

* * * * * /bin/sh /var/www/test.sh > /dev/null 2>&1

该文件只包含这一行:

php -q /var/www/test.php

该 php 文件包含以下内容:

<?php
$command = 'cairosvg -f pdf -o /var/www/test.pdf /var/www/test.svg';
system($command);
$command = 'mkdir /var/www/test_dir';
system($command);
file_put_contents('var/www/test_user.log', posix_getpwuid(posix_geteuid())['name']);
if (file_exists('/var/www/test.pdf')) {
    file_put_contents('/var/www/test.log', 'success');
} else {
    file_put_contents('/var/www/test.log', 'fail');
}

cairosvg 是一个将 SVG 文件转换为 PDF 的 CLI 库。如果我执行上述步骤,此 PHP 代码将运行,但未创建文件。如果我通过 URL 调用 PHP 文件,则会创建文件。

我看到的唯一区别是,进程用户posix_getpwuid(posix_geteuid())['name'] 在通过 URL 运行时是 www-data,在通过 shell 运行时是 root

cairosvg -f pdf -o /var/www/test.pdf /var/www/test.svg 命令在我自己以 root 身份在终端中运行时有效。

第二个命令,mkdir /var/www/test_dir 只是一个现实检查,以确保 system() 启用 CLI 或其他非常简单的东西。该命令适用于 shell 和 URL。

这是一个关于更复杂系统的问题的最小、完整和可验证的示例,因此“跳过 shell 步骤”或类似的答案对我没有太大帮助。

我正在运行 PHP 5.6、Ubuntu 14.04 和 Apache。

为什么这个 PHP 代码在我通过 shell 调用而不是通过 URL 调用时会失败?

【问题讨论】:

  • 投反对票的原因?
  • 看看system的返回值,它应该包含命令的输出。目标文件对您的用户是否可写?
  • @NicoHaase 感谢您的建议。我转储了exec 的输出,但它什么也没给出,但system 返回状态给出127。现在在谷歌上搜索。用户是 root,所以是的,它应该具有写访问权限。
  • @Goose 退出代码 127,显然表明您的 cli 不知道任何 cairosvg 命令。我建议使用二进制的完整路径
  • 请看一下这个优秀的答案并查看 cron 在受限环境中运行命令 serverfault.com/questions/449651/… 部分

标签: php linux shell


【解决方案1】:

这要归功于 cmets 中的 Nico Haase、pomaxa 和 kvantour。

system() 返回状态为 127。这表明用户 (root) 无法识别 cairosvg 命令。我将 /usr/bin/cairosvg 符号链接到 /usr/local/bin/cairosvg 并且一切正常。

shell 内部的 root 无法访问 cairosvg local 的原因是 CRON 在受限环境中运行您的命令下的explained here

可用的环境变量可能非常有限。通常,您只会定义几个变量,例如 $LOGNAME、$HOME 和 $PATH。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 2015-05-18
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多