【发布时间】: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/… 部分