socat espere pela resposta

socat espere pela resposta

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 secondstambé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 socatficaria em execução em segundo plano pelo tempo restante.

Em zsh, você precisaria adicionar um &no final do echo|socatpipeline para não esperar por isso. Na verdade, você pode querer adicioná-lo para bashestar preparado para o futuro, caso bashdecida mudar o comportamento no futuro.

Se a resposta puder ter mais de uma linha ou não for delimitada por nova linha, zshvocê 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 sysreadembutido fazum read()chamada de sistema de tamanho 8192. Isso pressupõe que socata resposta seja escrita no pipe emum write()chamada do sistema (o que acontece).

Portável, você sempre pode recorrer ddpara 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 socatficar 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"
  }
)

informação relacionada