Telnet smtp 命令 bash 2.05 脚本问题

Posted

技术标签:

【中文标题】Telnet smtp 命令 bash 2.05 脚本问题【英文标题】:Telnet smtp command bash 2.05 script problem 【发布时间】:2019-12-25 00:50:55 【问题描述】:

逐行有效,但在脚本中却不行。

我尝试了所有我能想到的。

这在 bash 2.05 中不起作用

   sleep 1; echo "helo localhost"; sleep 1; echo "mail from: test@maillinux.net"; sleep 1; echo "rcpt to: user@actualdomain.org"; sleep 1; echo "data"; sleep 1; echo "subject: test"; echo; echo "some text" ;echo "."; echo "quit";  | telnet mailserver.actualdomain.org 25

但如果你逐行进行

telnet mailserver.actualdomain.org 25
220...
helo localhost
250...ok
mail from: test@maillinux.net
250..ok
rcpt to: user@actualdomain.org
250...ok
data
354 Start mail input; end with <CRLF>.<CRLF>
subject: test

some text
.
quit

然后它工作,我收到邮件。 该脚本在较新的 bash 4.4 中工作,但我需要它在 2.05 中工作。 在我看来,它不回声“。”等结束并没有完成邮件......因此不发送它。 但是为什么???

我希望它发送邮件,但它没有

【问题讨论】:

echo "quit" 后面加上sleep 有什么不同吗? 是的! :) 最后睡觉...aaaa 我怎么没想到。谢谢 但为什么它在 bash 4.4 中有效? 如果我用sleep 2 替换每个sleep 1 并在echo "quit;" 之后添加一个sleep 2;,它适用于我的bash 2.05 和4.3.48。时间问题? 是的,也许是时机问题。我现在得到 250 ..响应邮件排队等待投递...在最后睡眠 1 之前我没有得到。它刚刚被外国主机关闭了连接。 【参考方案1】:

这可能是telnet的版本不同,而不是bash的版本。

在这样的管道中使用网络工具时的一个常见问题是它们如何处理标准输入上的 EOF。你需要是这样的行为:

您的输入被写入 telnet 的标准输入 ...发生这种情况时,telnet 开始将该输入发送到远程服务器... Telnet 的标准输入被赋予一个 EOF(文件结尾)。 此时某些损坏的 telnet 版本会立即退出。 ...telnet 不断将它从标准输入读取的所有内容发送到远程服务器。 ...telnet 完成将它读取的所有内容发送到远程服务器,然后关闭套接字的发送端(通过 FIN 数据包) ...服务器不断向客户端发送内容,直到它发送任何需要完成的响应,然后服务器通过发送另一个 FIN 关闭自己的端 telnet 打印在从服务器获得 FIN 之前获得的所有内容。 此步骤的完成是在正确编写的 telnet 实际退出时。

如上所述,实际上存在的许多 telnet 版本都是在假设它们将由人类而不是脚本使用的情况下编写的。他们不会在接收到 EOF 时通过线路发送缓冲内容,并在关闭接收端之前等待从服务器接收任何响应,而是在看到 EOF 时立即退出。


您可以通过在末尾添加延迟来解决此问题。

这是一个丑陋的 hack,最好用知道如何正确关闭套接字的工具来代替,但廉价而肮脏的方法看起来像这样:

 ...; echo "."; echo "quit"; sleep 2;  | telnet mailserver.actualdomain.org 25

对于新开发,请考虑使用专用工具,如 socat,或 netcat 的众多实现之一。

socat 记录在案的行为明确使其等待完成在其标准输入上接收到的内容的发送,并在退出之前打印通过套接字接收到的响应;只要它等待服务器响应的时间有超时,可以显式配置该超时。

【讨论】:

【参考方案2】:

同意查尔斯,这必须是不同版本的 telnet。还有一些想法,

    您可以简单地使用 expect 和 send 命令来自动执行 telnet 命令,
#!/user/bin/expect
spawn telnet localhost 25 <<EOF
hello localhost
mail from: local@localhost
rcpet to: user@localhost
data
Some data
.
EOF

或者,

    使用邮件命令创建一个文本文件并使用 netcat(如果 telnet 不支持流输入)

cat mailCmd.txt | nc 本地主机 25

    最好和最可靠的方法是使用诸如 socat 或 sendmail 之类的实用程序

sendmail user@localhost

【讨论】:

以上是关于Telnet smtp 命令 bash 2.05 脚本问题的主要内容,如果未能解决你的问题,请参考以下文章

Telnet smtp.mail - 必须先发出 STARTTLS 命令

在 Bash 脚本中将 Telnet 命令传递给 SSH

通过 Bash 脚本通过 Telnet 发送命令

如何从 bash 获取 telnet 命令的输出?

将 DKIM 与 SMTP TELNET 连接一起使用

SMTP 协议系列一