【问题标题】:Simulating sendmail with dummy script使用虚拟脚本模拟 sendmail
【发布时间】:2011-04-12 06:30:14
【问题描述】:

我创建了一个小的 shell 脚本,它将所有的输入记录到一个日志文件中,我认为我可以用它来替换 sendmail 二进制文件,从而实现一种简单的方法来模拟电子邮件传递,而无需实际设置一个工作的 sendmail .

然而,这失败了。由于我无法理解的原因。

我查看了 PHP mail.c 源代码,据我所知(请注意,我对 C 语言不是很熟练),PHP 执行并直接与二进制文件对话(在sendmail_path 中设置) .但是当我用我的脚本替换 sendmail 二进制文件时不会创建日志文件,并且替换 sendmail 的脚本在执行时总是会创建一个日志文件,无论是否存在输入。

脚本本身运行良好。它的返回码应该与 sendmail 的一致。不同的是,无论输入如何,我的脚本总是返回 0,因为我对检查输入是否有效并不感兴趣——只是我得到了一些。

是否有可能实现我想要的,即使用 sendmail 模拟器?

脚本源码如下:

#!/bin/bash

LOGDIR=/tmp/sendmail-sim
NOW=$(date +%Y%m%dT%H%M)
CNT=1
FILENAME="$LOGDIR/$NOW.$CNT.log"

while [ -f $FILENAME ]; do
    CNT=$(($CNT + 1))
    FILENAME="$LOGDIR/$NOW.$CNT.log"
done

echo "$0 $*" > $FILENAME

while read BUF
do
    echo $BUF >> $FILENAME
done

exit 0

附言。我当前的 sendmail(或者实际上是 postfix)确实收到了来自 PHP 的电子邮件,但我不想实际发送任何电子邮件或需要在开发中挖掘它的邮件队列。

【问题讨论】:

  • 确认 - 您的 sendmail 脚本在从命令行调用时有效,而不是从 PHP 调用?我不知道 PHP 运行时是如何工作的,但我想知道它是否正在尝试链接邮件二进制对象,而不是托管到 Unix 环境??
  • 是的,它有效。我还没有尝试过使用邮件命令。 (现在在电车上,但很快就会测试。)
  • @Jules:我现在已经使用mail 命令测试了我的脚本,并且可以确认它可以工作。现在我修改了脚本,它甚至可以正常工作。 (第一个版本虽然有效,但只读取stdin 直到出现空行,这导致消息部分被省略。)
  • 您应该将其标记为已回答。
  • @nikc:仅供参考,可以回答您自己的问题并接受它。这个问题对我很有用,因为我试图根据内容有条件地丢弃或将消息传递给 sendmail。

标签: macos bash sendmail


【解决方案1】:

如果您需要测试您的 PHP 应用程序在不实际发送电子邮件的情况下正确格式化和发送电子邮件的能力,我建议您使用 Pear Mail 包。摆弄你的系统不是一个好主意。

如果您使用 Pear 的 Mail,您可以通过将驱动程序从“sendmail”或“smtp”更改为“mock”,从 sendmail 切换到 smtp 以模拟邮件接口的实现。

http://pear.php.net/package/Mail/docs/latest/Mail/Mail.html

http://pear.php.net/package/Mail/docs/latest/Mail/Mail_mock.html

如果您的代码如下所示:

mail('me@example.com', 'My Subject', $message);

然后使用 PEAR Mail 将其更改为可测试:

include('Mail.php');
function sendEmail($recipient, $subject, $body, $driver = 'mail') {
    $m = Mail::factory("mail");
    $headers = array(
        "From"=>"me@example.com",
        "To" => $recipient,
        "Subject"=> $subject);
    $m->send($recipient, $headers, $body);
    return $m;
}

// In Production:
sendEmail('me@example.com', 'My Subject', $message);

// During testing:
$m = sendEmail('me@example.com', 'My Subject', $message, 'mock');
var_dump($m->sentMessages);

这很粗略,因为您应该使用 PHPUnit 或 SimpleTest,但这是另一个时间和地点的话题 :)

【讨论】:

  • 我很感激您的意见,但我需要一个无论技术如何都能工作的解决方案,而不仅仅是 PHP 脚本。 PHP 当然是写这篇文章的最初原因,但后来发现它很有用,例如外壳脚本。空运行可以在模拟中减少一层抽象。
  • 尽管我的示例是针对 PHP 的,但我认为您必须对其他语言使用类似的方法,而不是替换系统二进制文件。如果您更换它们,您将遇到问题。 1. 在您更换二进制文件之前,您的软件将在另一台机器上以不同方式运行。 2. 在同一台机器上运行的其他软件的行为方式与预期不同。
【解决方案2】:

与往常一样,问题是用户错误。所以,男孩和女孩,不要忘记检查所有相关文件夹的写入权限。

【讨论】:

  • 现在还不够!大多数发行版现在都带有配置为使用自己的 /tmp 的 Apache,请参阅:stackoverflow.com/questions/10752396/…。因此,如果 /tmp/sendmail-sim 写入“无”,请不要感到惊讶。
  • 我不会再使用这个了。改用 Mailcatcher 之类的东西 mailcatcher.me
【解决方案3】:

注意,如果你只是想抓取stdin并将其写入文件,则无需一次循环一行:可以编写

cat - >> $FILENAME

【讨论】:

    【解决方案4】:

    我过去曾为此目的使用过 Fakemail。它接受 SMTP 连接,但将所有邮件写入文件,而不是将它们作为电子邮件发送。有python和perl两种实现方式。

    http://www.lastcraft.com/fakemail.php

    我们设置 apache 来为 Fakemail 写入的目录提供服务。对于员工来说,这是查看 Fakemail 收到的邮件并审查内容、目的地等的一种快速简便的方法。由于各种原因,HTML 电子邮件的格式有点古怪,因此它对于审查 html 电子邮件的格式不是很有用.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-26
      • 2010-09-05
      • 1970-01-01
      • 2022-12-09
      • 2018-09-06
      • 2010-11-30
      相关资源
      最近更新 更多