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 seconds1 秒后响应可用。

有没有办法在收到第一条消息后立即停止命令?

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

相关内容