我在脚本中使用它
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"
}
)