![使用 socat 从 Unix 域套接字编写脚本先写后读](https://linux22.com/image/63000/%E4%BD%BF%E7%94%A8%20socat%20%E4%BB%8E%20Unix%20%E5%9F%9F%E5%A5%97%E6%8E%A5%E5%AD%97%E7%BC%96%E5%86%99%E8%84%9A%E6%9C%AC%E5%85%88%E5%86%99%E5%90%8E%E8%AF%BB.png)
我有一个简单的服务器监听 Unix 域套接字(在 CentOS 机器上,以防万一)。当我向套接字发送命令“DATE”时,它会写回一条欢迎消息,然后写回“2015 年 4 月 15 日”。我可以使用以下命令手动执行此操作:
socat - UNIX-CONNECT:/tmp/server.sock
但我现在想编写它的脚本。我可以通过将 echo 的输出管道传输到上面来将 DATE 命令发送到套接字,但随后 socat 仅返回欢迎消息。我不确定 socat 是否只返回前两行,或者在关闭套接字之前等待一段安静的时间,或者什么。例如:
echo "DATE" | socat - UNIX-CONNECT:/tmp/server.sock
如何让 socat 在断开连接之前捕获整个响应?我尝试过 -t 和 -T 参数让它等待 5 秒,但这没有效果,socat 立即返回。
答案1
在:
echo "DATE" | socat - UNIX-CONNECT:/tmp/server.sock
echo
writesecho\n
然后退出,关闭管道的写入端。
这会导致 eof 出现在-
地址的读取端。然后socat
关闭 unix 域套接字的“发送”端,并且只要在 0.5 秒内没有看到任何从套接字从另一个方向传入的内容就终止。
可以通过该选项增加 0.5 秒的超时时间-t
。所以:
echo DATE | socat -t 300 - UNIX-CONNECT:/tmp/server.sock
socat
将等待 5 分钟以获取日期回复或服务器关闭其连接的发送端,以先到者为准。
如果您的服务器在客户端关闭其发送端时中止,您可以保持客户端(管道左侧echo
:)运行,直到服务器终止连接(假设它在发送回复后立即关闭连接),您可以做类似的事情:
sh -c 'echo "$$"; echo DATA; exec sleep infinity' | {
IFS= read -r pid
socat -t0 - UNIX-CONNECT:/tmp/server.sock
kill -s PIPE "$pid" # terminate the client after the server shuts down
}
或者:
echo DATE | socat -t0 -,ignoreeof UNIX-CONNECT:/tmp/server.sock
(使用 时ignoreeof
,socat
忽略 eof 并继续尝试每秒读取更多内容。对于管道,eof 之后不会出现任何内容,但这仍然给了我们我们想要的:模拟仍然存在的客户端)。
或者在看到回复后立即终止:
sh -c 'echo "$$"; echo DATA; exec sleep infinity' | {
IFS= read -r pid
socat -t0 - UNIX-CONNECT:/tmp/server.sock | {
IFS= read -r welcome
IFS= read -r date
printf '%s\n' "$date"
}
kill -s PIPE "$pid" # terminate the client after the reply has been read
}