¡Donde hay una necesidad, hay una manera! Creo que es una buena lección bash ver cómo funciona la gestión de procesos y ipc. La mejor solución es, por supuesto, esperar. Pero la verdadera razón es que las tuberías pueden ser complicadas y muchos comandos están diseñados para esperar los datos, lo que significa que el proceso se convertirá en un zombie por razones que la bahía es difícil de predecir.Pero aprender cómo y por qué nos recuerda lo que está pasando bajo el capó .
Cuando dos procesos entablan una conversación, existe el peligro de que uno o ambos intenten leer datos que nunca llegarán . Las reglas de enfrentamiento deben ser claras como el cristal. Cosas como CRLF y codificación de caracteres pueden matar a la fiesta. Afortunadamente, dos socios cercanos como un script bash y su proceso hijo son relativamente fáciles de mantener en línea. Lo más fácil de perder es que bash es al iniciar un proceso hijo para casi todo lo que hace. Si puede hacer que trabaje con bash, sabrá a fondo lo que está haciendo.
El punto es que queremos hablar con otro proceso. Aquí hay un servidor:
# a really bad SMTP server
# a hint at courtesy to the client
shopt -s nocasematch
echo "220 $HOSTNAME SMTP [$$]"
while true
do
read
[[ "$REPLY" =~ ^helo\ [^\ ] ]] && break
[[ "$REPLY" =~ ^quit ]] && echo "Later" && exit
echo 503 5.5.1 Nice guys say hello.
done
NAME=`echo "$REPLY" | sed -r -e 's/^helo //i'`
echo 250 Hello there, $NAME
while read
do
[[ "$REPLY" =~ ^mail\ from: ]] && { echo 250 2.1.0 Good guess...; continue; }
[[ "$REPLY" =~ ^rcpt\ to: ]] && { echo 250 2.1.0 Keep trying...; continue; }
[[ "$REPLY" =~ ^quit ]] && { echo Later, $NAME; exit; }
echo 502 5.5.2 Please just QUIT
done
echo Pipe closed, exiting
Ahora, el guión que con suerte hace la magia.
# Talk to a subprocess using named pipes
rm -fr A B # don't use old pipes
mkfifo A B
# server will listen to A and send to B
./smtp.sh <A> B &
# If we write to A, the pipe will be closed.
# That doesn't happen when writing to a file handle.
exec 3>A
read < B
echo "$REPLY"
# send an email, so long as response codes look good
while read L
do
echo "> $L"
echo $L > A
read < B
echo $REPLY
[[ "$REPLY" =~ ^2 ]] || break
done <<EOF
HELO me
MAIL FROM: me
RCPT TO: you
DATA
Subject: Nothing
Message
.
EOF
# This is tricky, and the reason sane people use Expect. If we
# send QUIT and then wait on B (ie. cat B) we may have trouble.
# If the server exits, the "Later" response in the pipe might
# disappear, leaving the cat command (and us) waiting for data.
# So, let cat have our STDOUT and move on.
cat B &
# Now, we should wait for the cat process to get going before we
# send the QUIT command. If we don't, the server will exit, the
# pipe will empty and cat will miss its chance to show the
# server's final words.
echo -n > B # also, 'sleep 1' will probably work.
echo "> quit"
echo "quit" > A
# close the file handle
exec 3>&-
rm A B
Tenga en cuenta que no estamos simplemente abandonando los comandos SMTP en el servidor. Verificamos cada código de respuesta para asegurarnos de que todo esté bien. En este caso, las cosas no serán OK y la secuencia de comandos se bloqueará.
Eso sirvió a mi propósito. No estaba seguro de dónde iría la salida estándar. – rup