PHP的popen命令失败的原因

发布于 2024-10-31 09:46:30 字数 1386 浏览 1 评论 0原文

我有一个批量电子邮件流程,可发送大约 30,000 封电子邮件。我遇到了一个奇怪的问题,该过程完成了大约 85%,然后电子邮件开始失败,并显示消息 无法执行:/usr/sbin/sendmail 我正在使用一个名为的库PHPMailer 1.73 以及错误消息来自的相关代码是

if(!@$mail = popen($sendmail, "w"))
{
    $this->SetError($this->Lang("execute") . $this->Sendmail);
    return false;
}

$sendmail 的值的形式为: /usr/sbin/sendmail -oi -f [电子邮件受保护] -t

我有 set_time_limit(0); 这样脚本就不会超时。

无论如何,有没有办法弄清楚为什么 popen() 突然开始失败?操作系统是否会耗尽文件描述符或达到其他限制?

我应该如何解决这个问题?我应该让它休眠,然后在失败之前重试 popen() 几次吗?

更新:感谢 Marko 的建议,查看我在 proc_open 文档 一条注释,如果它返回 FALSE ,则可能意味着您用完了文件描述符,或者您内存不足。我发现我的进程占用了 20G 内存。但是,如果将 memory_limit 设置为 64M,怎么会占用那么多内存呢?好吧,看来使用 exec()popen()proc_open() 运行外部程序并不会计入 PHP 的内存限制。有关详细信息,请参阅此问题,调试 mod_php 中的内存使用情况。我仍然不确定这是如何发生的,但我怀疑存在某种内存泄漏。

总之,如果文件描述符或内存不足,popen()proc_open() 可能会返回 FALSE

I have a batch email process that sends about 30,000 email messages. I have ran into a strange problem where it gets to about 85% completion of the process and then the email start failing with the message Could not execute: /usr/sbin/sendmail I am using a library called PHPMailer 1.73 and the relevant code where the error message comes from is

if(!@$mail = popen($sendmail, "w"))
{
    $this->SetError($this->Lang("execute") . $this->Sendmail);
    return false;
}

The value of $sendmail is of the form: /usr/sbin/sendmail -oi -f [email protected] -t

I have set_time_limit(0); so the script will not timeout.

Is there anyway to figure out why all of a sudden popen() starts failing? Could the OS be running out of file descriptors or some other limit being reached?

How should I resolve this? Should I have it sleep and then retry the popen() several times before failing?

Update: Thanks to the suggestion of Marko to check out proc_open() I found on the proc_open documentation a comment that if it returns FALSE it probably means that you ran out of file descriptors or you are out of memory. I found that my process was taking 20G of memory. But how could it take that much memory if memory_limit is set at 64M? Well, it seems that running external programs with exec(), popen() or proc_open() do NOT count against PHP's memory limit. See this SO question for more info on that, Debugging memory usage in mod_php. I'm still not sure how this is happening but I suspect some sort of memory leak.

In summary, popen() and proc_open() can return FALSE if you are out of file descriptors or out of memory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你另情深 2024-11-07 09:46:30

我建议使用 proc_open 代替。它使用起来稍微复杂一些,但是可以让您访问 stdout 和 stderr。这两个管道上的消息将为您节省大量调试时间。

如何使用,只需阅读PHP文档中的示例和注释即可。

I would recommend to use proc_open instead. It is slightly more complex to use, but gives you access to stdout and stderr. The messages on this two pipes will save you a lot of debugging time.

How to use, just read the examples and comments in the PHP documentation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文