telnet smtp命令bash 2.05脚本问题

Telnet smtp command bash 2.05 script problem

逐行有效,但在脚本中无效。

我能想到的都试过了

这在 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。 在我看来,它不会回显“。” et 结束并没有完成邮件...因此不发送它。 但为什么???

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

这可能是 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, or one of the many implementations of netcat 这样的专用工具。

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

同意 Charles 的观点,这一定是不同版本的 telnet。还有一些想法,

  1. 您可以简单地使用 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

或者,

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

cat mailCmd.txt | nc localhost 25

  1. 最好和可靠的方法是使用像 socat 或 sendmail 这样的实用程序

sendmail user@localhost < "Emailcontent.txt"