Cierre de conexiones a través de s_client en un script de shell

Estoy tratando de hacer una conexión a un servidor IMAP dentro de un script de shell. Si bien puedo conectarme y emitir los comandos, parece imposible cerrar la conexión adecuadamente.

Este es el comando de prueba que estoy usando:

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

Debido a que la conexión se cierra tan pronto como se agota la entrada, esto ocurre antes de que se reciba cualquier salida, por lo que nunca recibo los datos requeridos.

Si agrego la opción-ign_eof opción para que ignore el final de la entrada para mantener la conexión abierta, la salida se devuelve como se desea. Pero en cambio después de que se haya cerrado la conexión ...

* BYE Logging out
03 OK Logout completed.

... s_client permanece vivo por lo que la ejecución nunca regresa al script.

¿Hay alguna solución que haga que s_client termine cuando el servidor cierre la conexión?

¿O hay un método alternativo utilizando herramientas estándar? El script se ejecutaría en Mac OS X, Debian y un derivado de Redhat, y posiblemente un emulador de terminal de Android, así que me gustaría usar herramientas bastante estándar para la portabilidad en lugar de paquetes especializados.

Actualización: se me ocurrió una respuesta con la que no estoy del todo satisfecho, pero que funciona. Utiliza una secuencia de comandos para canalizar los comandos al openssl, pero luego ingresa en un bucle infinito para mantener abierto el stdin hasta que reciba una señal para que se lo deje. Aquí está mi script de prueba:

#!/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."

El script se llama a sí mismo con un parámetro para generar los comandos IMAP que se canalizan a openssl, cuya salida se canaliza a unread Bucle para que pueda ser procesado. La variable MYFLAG se usa solo para ocultar la salida de información por openssl y simplemente se hace eco de la salida de la conexión del servidor.

Seleccioné un nombre de carpeta ficticia que incluye el PID de la segunda instancia del script como una forma de pasar esto de vuelta, obviamente un archivo temporal hubiera sido mejor, pero para las pruebas quería mantener todo auto contenido y poder ver qué estaba pasando.

Una vez que se muestra la información de recuperación y el servidor devuelve la respuesta OK, envía una señal SIGUSR1 a la segunda instancia de la secuencia de comandos, que luego envía el mensaje de cierre de sesión y se cierra, cerrando la entrada, lo que hace que s_client se desconecte.

Originalmente incluí el04 logout comando en el conjunto inicial de ecos, pero cuando hice esto, el bucle de lectura solo se mostraba hasta el momento en que la salida de recuperación se detuvo, ni siquiera mostraba el estado OK para la operación, aunque todo fue recibido.

También necesito usartr para eliminar los retornos de carro de salida, pero si canalizo la salida de openssl through, entonces el bucle de lectura no recibe nada.

Respuestas a la pregunta(1)

Su respuesta a la pregunta