Linux

使用 socat 從 Unix 域套接字進行腳本寫入然後讀取

  • October 3, 2020

我有一個簡單的伺服器在 Unix 域套接字上偵聽(在 CentOS 機器上,以防這很重要)。當我將命令“DATE”發送到套接字時,它會寫回一條歡迎消息,然後是“APRIL 15 2015”。我可以使用以下命令手動執行此操作:

socat - UNIX-CONNECT:/tmp/server.sock

但我現在想編寫腳本。我可以通過管道將 echo 的輸出發送到上面的套接字,將我的 DATE 命令發送到套接字,但隨後 socat 只返回歡迎消息。我不確定 socat 是只返回前兩行,還是在關閉套接字之前等待一段安靜的時間,或者什麼。例如:

echo "DATE" | socat - UNIX-CONNECT:/tmp/server.sock

如何讓 socat 在斷開連接之前擷取整個響應?我試過 -t 和 -T 參數讓它等待 5 秒,但這沒有效果,socat 立即返回。

在:

echo "DATE" | socat - UNIX-CONNECT:/tmp/server.sock

echo寫入echo\n然後退出,關閉管道的寫入端。

這會導致在-地址的讀取端看到 eof。然後socat關閉 unix 域套接字的“發送”端並終止,只要在 0.5 秒內沒有看到任何從套接字的另一個方向進入。

可以使用該-t選項增加 0.5 秒超時。所以:

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
}

引用自:https://unix.stackexchange.com/questions/196278