socat ждать ответа

socat ждать ответа

Я использую это в сценарии.

echo $(echo "sign 00:07:32:46:04:75" | socat UDP4-DATAGRAM:239.192.0.2:9000 -)

но это немедленно останавливается и я не получаю ответа от сервера

если я сделаю

echo $(echo "sign 00:07:32:46:04:75" | socat -t5 UDP4-DATAGRAM:239.192.0.2:9000 -)

он всегда ждет 5 secondsтакже, когда ответ будет доступен через 1 секунду.

Есть ли способ остановить команду сразу после получения первого сообщения?

решение1

Предполагая, что ответ представляет собой одну строку текста, разделенную символом новой строки, с помощью bash, вы всегда можете сделать:

IFS= read -r answer < <(
  echo 'sign 00:07:32:46:04:75' |
    socat -t 5 - UDP4-DATAGRAM:239.192.0.2:9000)

Он вернется, как только поступит ответ, и socatбудет работать в фоновом режиме в течение оставшегося времени.

В zsh, вам нужно добавить &в конце конвейера, echo|socatчтобы он не ждал его. Вы можете на самом деле захотеть добавить его bashтакже, чтобы быть готовым к будущему, если bashрешит изменить поведение в будущем.

Если ответ может быть больше одной строки или не разделен новой строкой, zshможно сделать следующее:

zmodload zsh/system
(echo 'sign 00:07:32:46:04:75' |
  socat -t 5 - UDP4-DATAGRAM:239.192.0.2:9000 &) | sysread answer

Встроенный sysreadделаетодин read()системный вызов размером 8192. Это предполагает, что socatответ записывается в конвейер водин write()системный вызов (что он и делает).

Для этого вы всегда можете прибегнуть к портативным средствам dd:

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
)

(обратите внимание, что подстановка команды удаляет все конечные символы новой строки).

Если вы не хотите терять socatвремени еще несколько секунд после этого, вы можете сделать что-то вроде:

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"
  }
)

Связанный контент