Yo uso esto en un script
echo $(echo "sign 00:07:32:46:04:75" | socat UDP4-DATAGRAM:239.192.0.2:9000 -)
pero esto se detiene inmediatamente y no recibo respuesta del servidor
si lo hago
echo $(echo "sign 00:07:32:46:04:75" | socat -t5 UDP4-DATAGRAM:239.192.0.2:9000 -)
Siempre espera 5 seconds
también cuando la respuesta esté disponible después de 1 segundo.
¿Hay alguna manera de detener el comando inmediatamente después de recibir el primer mensaje?
Respuesta1
Suponiendo que la respuesta es una línea de texto delimitada por una nueva línea, con bash
, siempre puedes hacer:
IFS= read -r answer < <(
echo 'sign 00:07:32:46:04:75' |
socat -t 5 - UDP4-DATAGRAM:239.192.0.2:9000)
Eso regresará tan pronto como haya una respuesta y socat
se dejará ejecutándose en segundo plano durante el tiempo restante.
En zsh
, necesitaría agregar un &
al final de la echo|socat
canalización para que no tenga que esperar. Es posible que desee agregarlo bash
también para estar preparado para el futuro en caso de que bash
decida cambiar el comportamiento en el futuro.
Si la respuesta puede tener más de una línea o no está delimitada por una nueva línea, podrías zsh
hacer:
zmodload zsh/system
(echo 'sign 00:07:32:46:04:75' |
socat -t 5 - UDP4-DATAGRAM:239.192.0.2:9000 &) | sysread answer
El sysread
incorporado lo haceuno read()
llamada al sistema de tamaño 8192. Eso supone socat
que escribe la respuesta en la tubería enuno write()
llamada al sistema (lo cual hace).
Portablemente, siempre puedes recurrir a dd
eso:
answer=$(
(echo 'sign 00:07:32:46:04:75' |
socat -t 5 - UDP4-DATAGRAM:239.192.0.2:9000 &) |
dd bs=8192 count=1 2> /dev/null
)
(tenga en cuenta que la sustitución de comandos elimina todos los caracteres de nueva línea finales).
Si quieres evitar socat
quedarte esperando esos segundos adicionales después de eso, puedes hacer algo como:
answer=$(
(echo 'sign 00:07:32:46:04:75' |
sh -c 'echo "$$"
exec socat -t 5 - UDP4-DATAGRAM:239.192.0.2:9000 &
) | {
IFS= read pid
dd bs=8192 count=1 2> /dev/null
kill -s PIPE "$pid"
}
)