Закрытие соединения через s_client в скрипте оболочки

Я пытаюсь установить соединение с сервером IMAP в сценарии оболочки. Несмотря на то, что я могу подключиться и выдать команды, закрытие соединения подходящим образом кажется невозможным.

Это тестовая команда, которую я использую:

openssl s_client -crlf -connect server:993 <<EOF
01 login USERNAME PASSWORD
02 LIST "" "*"
03 logout
EOF

Поскольку соединение закрывается, как только заканчивается вход, это происходит до того, как любой выход получен, поэтому я никогда не получаю требуемые данные.

Если я добавлю опцию-ign_eof опция, так что он будет игнорировать окончание ввода, чтобы сохранить соединение открытым, выход возвращается по желанию. Но вместо этого после того, как соединение было закрыто ...

* BYE Logging out
03 OK Logout completed.

... s_client остается живым, поэтому выполнение никогда не возвращается к сценарию.

Есть ли решение, которое заставит s_client завершать работу, когда сервер закрывает соединение?

Или есть альтернативный метод с использованием стандартных инструментов? Сценарий будет работать на Mac OS X, Debian и производной от Redhat, и, возможно, на эмуляторе терминала Android, поэтому я хотел бы использовать довольно стандартные инструменты для переносимости, а не специализированные пакеты.

Обновление: я пришел с ответом, который меня не совсем устраивает, но который работает. Он использует сценарий для передачи команд в openssl, но затем вводит бесконечный цикл, чтобы держать stdin открытым, пока не получит сигнал, чтобы он сказал, что нужно выйти. Вот мой тестовый скрипт:

#!/bin/sh

if [ "$1" = "doit" ]; then
   trap "echo \"04 logout\"; exit" SIGUSR1
   echo "00 login USERNAME PASSWORD"
   echo "01 SELECT PID-$"
   echo "02 SELECT FOLDER"
   echo "03 FETCH 1:* (BODY[HEADER.FIELDS (Subject)])"
   while :; do :; done
fi

MYFLAG=
$0 doit | openssl s_client -crlf -connect server:993 2>/dev/null | while read LINE; do
   LINE=`echo "$LINE" | tr -d '\r'`
   [ "${LINE:0:4}" = "* OK" ] && MYFLAG=Y 
   [ "${LINE:0:33}" = "01 NO Mailbox doesn't exist: PID-" ] && PID="${LINE##*PID-}"
   [ "$MYFLAG" ] && echo "$LINE"
   [ "$PID" -a "$LINE" = "03 OK Fetch completed." ] && kill -USR1 $PID
done
echo "Finished."

Сценарий вызывает себя с параметром для вывода команд IMAP, которые передаются в openssl, чей вывод передается вread цикл, чтобы он мог быть обработан. Переменная MYFLAG просто используется, чтобы скрыть информацию, выводимую openssl, и просто отображать вывод из соединения с сервером.

Я выбираю фиктивное имя папки, которое включает в себя PID второго экземпляра скрипта, чтобы передать его обратно, очевидно, что временный файл был бы лучше, но для тестирования я хотел сохранить все самодостаточным и иметь возможность наблюдать за тем, что происходило.

Как только информация о выборке отображена, и сервер возвращает ответ OK, он отправляет сигнал SIGUSR1 во второй экземпляр сценария, который затем отправляет сообщение о выходе из системы и завершает работу, закрывая stdin, что приводит к отключению s_client.

Первоначально я включил04 logout команда в начальном наборе echos, но когда я сделал это, цикл чтения отображался только до тех пор, пока вывод выборки не остановился, он даже не показывал состояние OK для операции, хотя все было получено.

Также мне нужно использоватьtr для удаления завершающих возвратов каретки, но если я передаю вывод из openssl, то цикл чтения ничего не получит.

Ответы на вопрос(1)

Ваш ответ на вопрос