如何解决Crontab 通过 exec() 不适用于 PHP 7.4/Deb 10
调试有点困难,因为我正在使用新版本的 PHP 和新服务器上的新操作系统。
我有一个用 PHP 编写的 cron 管理系统,它也允许我添加/删除或启用/禁用 cronjobs。
在另一个当前使用 PHP 7.2 的 Deb 8 服务器上,它可以完美地使用以下函数来创建作业...
public static function createCronjob($job)
{
exec('echo -e "`crontab -l`\n'. $job .'" | crontab -',$output);
return $output;
}
其中 $job
类似于:
10 0 * * * wget -O - https://website.com/cxs?job=jobTitle >/dev/null 2>&1
而且我还可以用这个列出 crontab 的内容,它还会输出两个单独的数组,一个用于活动作业,另一个用于非活动作业...
public static function getCronjobs()
{
exec('crontab -l',$data);
$active = [];
$inactive = [];
foreach ($data as $j) {
if (!empty($j)) {
if (substr($j,1) == '#') {
array_push($inactive,$j);
} else {
array_push($active,$j);
}
}
}
$arr = [
'active' => $active,'inactive' => $inactive
];
return $arr;
}
但我刚刚用 PHP 7.4 设置了一个新的 Debian 10 服务器,但这些似乎都没有做任何事情了?它不会添加工作并且 crontab -l
总是返回一个空数组(我认为这是因为没有找到工作)。
我已经检查过 exec()
是否正常工作,并按照我发现的几篇文章的建议尝试将 www-data
用户添加到 /etc/cron.allow
,尽管我从未在Deb 8 服务器,但我一点也不高兴。
Deb 10 或 PHP 7.4 中是否引入了我不知道的新安全措施或代码更改,这会阻止它正常工作,或者我在这里遗漏了什么明显的东西?
-- 编辑以包含下面@summea 提供的解决方案-
我相信其他人会偶然发现这个,所以这里是答案:
a) PHP 7.4(似乎是 7.3)需要 echo
中 exec()
的完整路径
public static function createCronjob($job)
{
exec('/usr/bin/echo -e "`crontab -l`\n'. $job .'" | crontab -',$output);
return $output;
}
但奇怪的是,crontab
的完整路径不需要(但可能是很好的做法),因为这仍然有效:
exec('crontab -l',$data);
b) 创建 /etc/cron.allow
对我来说是一个错误。它拒绝所有未在此文件中声明的其他用户访问 crontab
。在我删除它并重新启动 cron 服务 /etc/init.d/cron restart
后,一切正常。
真的希望这可以为其他人节省一些时间,因为它是个骗子!
解决方法
我的本地计算机上有一个 Debian 10 虚拟机,上面有 PHP 7.3.19。经过大量时间尝试解决您面临的问题的不同方法后,在我看来,问题与需要包含 echo
程序的完整路径有关。我不知道我的机器上是否还有一些其他的 echo
程序,PHP 在不同的路径中找到了它(这可能与 Michael was saying in the comment from earlier 的内容间接相关)。有一次我想知道命令中的反引号是否会导致 PHP 出现问题,因为 shell_exec()
is evidently like the PHP backtick operator.
为了让您的 createCronjob()
从 PHP 方面成功运行,我做了以下工作:
// ref: q21.php
function createCronjob($job)
{
exec('/usr/bin/echo -e "`crontab -l`\n'. $job .'" | crontab -',$output);
return $output;
}
当我将完整路径添加到 echo
命令时,它开始工作。您的 echo
路径可能不同,但也可能相同,因为我们应该使用类似的系统。
我使用以下命令找到了 echo
路径:
which echo
它返回了这个位置:
/usr/bin/echo
另外,为了将来参考,我不知道在这种情况下,将来使用 escapeshellcmd()
是否可能是一个好主意?我对它不是很熟悉,所以我不确定在这种情况下您是否希望将它包含在 shell 命令的某处(无论如何它可能会使命令无法按预期运行),但想提一下它!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。