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

相關內容