Eu uso isso em um script
echo $(echo "sign 00:07:32:46:04:75" | socat UDP4-DATAGRAM:239.192.0.2:9000 -)
mas isso para imediatamente e não recebo resposta do servidor
se eu fizer
echo $(echo "sign 00:07:32:46:04:75" | socat -t5 UDP4-DATAGRAM:239.192.0.2:9000 -)
ele sempre espera 5 seconds
também quando a resposta estará disponível após 1 segundo.
Existe uma maneira de interromper o comando imediatamente após receber a primeira mensagem?
Responder1
Supondo que a resposta seja uma linha de texto delimitada por nova linha, com bash
, você sempre pode fazer:
IFS= read -r answer < <(
echo 'sign 00:07:32:46:04:75' |
socat -t 5 - UDP4-DATAGRAM:239.192.0.2:9000)
Isso retornaria assim que houvesse uma resposta e socat
ficaria em execução em segundo plano pelo tempo restante.
Em zsh
, você precisaria adicionar um &
no final do echo|socat
pipeline para não esperar por isso. Na verdade, você pode querer adicioná-lo para bash
estar preparado para o futuro, caso bash
decida mudar o comportamento no futuro.
Se a resposta puder ter mais de uma linha ou não for delimitada por nova linha, zsh
você poderá fazer:
zmodload zsh/system
(echo 'sign 00:07:32:46:04:75' |
socat -t 5 - UDP4-DATAGRAM:239.192.0.2:9000 &) | sysread answer
O sysread
embutido fazum read()
chamada de sistema de tamanho 8192. Isso pressupõe que socat
a resposta seja escrita no pipe emum write()
chamada do sistema (o que acontece).
Portável, você sempre pode recorrer dd
para isso:
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
)
(observe que a substituição do comando remove todos os caracteres de nova linha à direita).
Se você quiser evitar socat
ficar por alguns segundos extras depois disso, você pode fazer 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"
}
)