我编写了curl php脚本,它的工作原理是在成功登录后从一个网站下载csv文件。当我在浏览器中启动它时,它运行良好,但当我将它放在cron作业列表中时,它失败了。我曾经在日志中看到内存耗尽的错误,所以我想我的服务器给了我更少的cron内存。
我该如何解决这个问题?
你可以看到代码的一部分,它正在进行下载工作,这很常见:
<?php
...
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt ($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $postfields);
$fp = fopen("data.csv", "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_exec ($ch);
curl_close ($ch);
fclose($fp);
我只想再说一遍,这是代码的一部分,在浏览器中一切正常,在cron作业中失败。
假设您使用的是CRON的标准配置,您的cwd
(当前工作目录)是~/
或/
或类似的目录,但是当您从web运行脚本时,您的cwd
设置为dir( __FILE__)
(当前脚本目录)。
假设您使用的是脚本/var/www/web1/scripts/script1.php
,而不是:
- 腹板cwd=
/var/www/web1/scripts/
- CRON cwd=
/var/www
当您使用相对文件名,如data.csv
(开头没有/
)时,完整路径将创建为CWD . $filename
,因此:
- 腹板全路径
/var/www/web1/scripts/data.csv
- CRON完整路径
/var/www/data.csv
您可以通过使用轻松避免这种情况
define( 'PATH_ROOT', dirname( __FILE__) . '/');
// ...
curl_setopt ($ch, CURLOPT_COOKIEJAR, PATH_ROOT . 'cookie.txt');
curl_setopt ($ch, CURLOPT_COOKIEFILE, PATH_ROOT . 'cookie.txt');
// ...
$fp = fopen( PATH_ROOT . "data.csv", "w");
还要确保您的系统用户已连接,并且脚本将运行(检查CRON long或给自己发电子邮件)。
通常这意味着在调用服务器和通过命令行调用时,PHP(PHP.ini)的配置是不同的。我不确定这是否是最佳实践,但我通常会让我的cronjob在我的脚本上调用wget,以确保它们在我测试它们的同一环境中运行,即通过Web服务器。
# m h dom mon dow command
* * * * * wget -O - http://myapp.example.com/cron/run > /dev/null 2>&1
*表示该命令将在以下任意位置运行:
- 分钟
- 小时
- 每月的哪一天
- 月
- 星期几
-O选项告诉wget不要将脚本的输出写入文件">/dev/null 2>&1"只是重定向脚本的输出,以避免cron的默认行为(即向用户发送带有命令输出的电子邮件)。
作为一种变通方法,您可以在浏览器中执行此操作,而无需修改PHP脚本。例如:
30 * * * * /usr/bin/lynx -source http://mypage/status/cron > /dev/null
它的行为就像在浏览器中一样,可以避免您处理代码和环境问题。
或者,您可以使用wget来代替PHP脚本。
"php/home7/philbike/public_html/atlandicauto/assets/components/cronmanager/cron.php"命令怎么样?它在你的终端上工作吗?
最后,使用我的第一个设置:cd /home7/philbike/public_html/atlanticauto/assets/components/cronmanager/ && php cron.php
,一切正常。
我应该在不使用系统变量的情况下原样写入csv文件的路径:
/home7/philbike/public_html/atlanticauto/data.csv