php - 通过 exec() 的 Crontab 不适用于 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,0,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 VM,上面有 PHP 7.3.19。经过大量时间尝试解决您面临的问题的不同方法后,在我看来,问题与需要包含echo
程序的完整路径有关。我不知道echo
我的机器上是否有其他程序 PHP 在不同的路径中找到了或其他东西(这可能与Michael 在之前的评论中所说的间接相关)。有一次我想知道命令中的反引号是否导致 PHP 出现问题,因为shell_exec()
它显然类似于 PHP 反引号运算符。
这是我为使您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 命令中的某个地方(并且它可能会使命令无论如何都不能按预期运行),但想提一下它!
推荐阅读
- python - 更新模型打破了过去的 Alembic 迁移
- android - 关于 Android 日志 [anr]、[ramoops]、[tombstone] 和 [Crash0.txt]
- python - 如何使用 .loc 解决 SettingWithCopyWarning?
- wordpress - WooCommerce 所有订阅产品都弄乱了我的订单号
- quasar-framework - Quasar 是否支持基于 Git 的博客?
- javascript - 将数据从路由器视图发送到 App.vue
- git - git checkout 是做什么的?
- react-native - 当我使用 redux 添加项目时,一直不确定
- ios - 当我使用 Unity Flutter Widget 时,Xcode 中的存档出现在其他项目下
- python - 具有多个输入特征和多个输出的 LSTM