Не работают, потому что ввод/вывод получается несинхронизированный. Ты вываливаешь все сразу, а нужно чтоб была последовательность запрос-ответ. Смотреть нужно в сторону expect.
Вроде такого:#!/usr/bin/expect
spawn telnet smtp.mail.com 25
expect "220 "
send "lhlo localhost\n"
expect "250 "
send "mail from: <john@yandex.ru>\n"
expect "250 "
send "rcpt to: <alisa@mail.ru>\n"
expect "250 "
send "data\n"
expect "354 "
send "Test message string 0
Test message string 1
Test message string 2
Test message string 3
Test message string 4
Test message string 5
Test message string 6
Test message string 7
Test message string 8
Test message string 9
.
"
expect "250 "
send "quit\n"
expect eof
Ну, естесственно по уму ошибки там обрабатывать нужно и т.д. Expect предоставляет достаточно гибкие языковые средства и позволяет все это делать.
Если expect не катит, можно на perl'е налабать или еще на чем-нибудь...