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

答えが改行で区切られた 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|socatbashbash

回答が複数行になる場合や改行で区切られていない場合は、zsh次のようにします。

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

組み込み関数sysread1つ read()システムコールのサイズは8192です。これは、socatパイプに答えを書き込むことを前提としています。1つ 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"
  }
)

関連情報