LINUX.ORG.RU

шелл и закрытие потоков


0

0

Исходная задача: сопрячь nmh и msmtp-enqueue. Получилось что нужно написать шелл-скрипт, который будет вызываться вместо sendmail -bs

То есть он должен через свои stdin и stdout разговаривать по SMTP-протоколу.

Стал я такой скрипт писать. Пока только тестирую, как это вообще работает. Сделал я его через перемежающиеся строки head -n1 >> some_file и echo something

пока обмен идет по одной строке с его стороны, то все нормально. Несколько первых сообщений мы обменялись. С помощью head -n1 я получаю эту строку. Но в конце мне нужно получить само сообщение и принять его до завершающей точки. И тут непонятная мне проблема. Если я в это месте просто поставлю cat >> some_file то я все это сообщение (много строк) приму. Но я не смогу ответить на него "Message accepted for delivery" потому что он не выходит из этого ката. А если я попытаюсь сделать в цикле (или просто несколько) head -n 1, то он не проходит дальше первого head'a

★★★★★

Вот пример скрипта на котором я тестирую SMTP-разговор:

#!/bin/sh

echo 220 chup.gado ESMTP Sendmail 8.13.5.20060308/8.13.3; `date`
head -n 1 > /tmp/inp
sleep 1
cat << EOF
250-chup.gado Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-DELIVERBY
250 HELP
EOF
head -n 1 >> /tmp/inp

sleep 1
echo 500 5.5.1 Command unrecognized: "ONEX"

head -n 1 >> /tmp/inp

sleep 1
echo "250 2.1.0 <dlagno@rambler.ru>... Sender ok"

head -n 1 >> /tmp/inp

sleep 1
echo "250 2.1.5 <dilmah@netman.ru>... Recipient ok (will queue)"

head -n 1 >> /tmp/inp

sleep 1
echo "250 2.1.5 <zapata@mail.ru>... Recipient ok (will queue)"

head -n 1 >> /tmp/inp

sleep 1
echo "354 Enter mail, end with "." on a line by itself"

head -n 1 >> /tmp/inp
head -n 1 >> /tmp/inp
head -n 1 >> /tmp/inp
head -n 1 >> /tmp/inp
head -n 1 >> /tmp/inp

until grep '^\.$' /tmp/inp > /dev/null; do
    head -n 1 >> /tmp/inp
done

sleep 1
echo "250 2.0.0 k498r6Sd014323 Message accepted for delivery"

cat >> /tmp/inp

dilmah ★★★★★
() автор топика
Ответ на: комментарий от dilmah

Затык идет в самых последних head'ах -- я не могу считать более одной строки. А если заменяю их на cat >> file то я считтываю много строк, но не могу выйти оттуда и обнаружить точку.

dilmah ★★★★★
() автор топика

Вообще, такое на шелле писать -- порядочный гемморой, на Перле это проще на порядок.

А head' ом ты поток, очевидно, не прочитаешь: первый же head тебе всю задницу отгрызет.

Делай read в цикле и анализируй прочитанную переменную.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

read попробую.

> А head' ом ты поток, очевидно, не прочитаешь: первый же head тебе всю задницу отгрызет.

а вот тут непонятно. Несколько первых строк читаются успешно. Вот лог того файла /tmp/inp куда направляется head:

EHLO chup.gado
ONEX
MAIL FROM:<dlagno@rambler.ru>
RCPT TO:<dilmah@netman.ru>
RCPT TO:<zapata@mail.ru>
DATA
From: "Denis Lagno" <dlagno@rambler.ru>
RSET

Все это считано последовательностью head'ов




dilmah ★★★★★
() автор топика
Ответ на: комментарий от dilmah

> Несколько первых строк читаются успешно. 

А он (head) сразу закрывает файл, если после тех сторок,
которые его попросили вывести, его читалка блокируется. Поэтому
при построчном скармливании все сработает.

Вот такое:

будет работать примерно как ты ожидаешь, если его позвать и скармливать ему stdin по строчакм, но не так, как ты хочешь,
если ему скормить сразу файл (типа script<filename или 
cat filename |script):
#!/bin/sh
echo -n ONE=
head -n 1
echo -n TWO=
head -n 1
echo -n THREE=
head -n 1


А тебе надо примерно это:
#!/bin/sh
read
echo ONE=$REPLY
read
echo TWO=$REPLY
read
echo THREE=$REPLY

Die-Hard ★★★★★
()
Ответ на: комментарий от sdio

замена head -n1 на read прошла нормально, все работает. Теперь я посылаю почту из nmh используя msmtp:)

dilmah ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.