
我的目標是使用nc
單一fifo
.我並不是在尋找最好的方法,我只是想理解以下命令的語義(分叉何時發生,為什麼,它會改變什麼,為什麼命令的行為不同...)。
我使用的是 Bash,所以我不確定是否所有命令都適用於 POSIXsh
或zsh
, ksh
, ...
這是我在標題中提到的四個命令(假設我已經這樣做了mkfifo fifo
):
cat fifo | nc -l localhost 8888 > fifo
exec 3<> fifo && nc -l localhost 8888 <&3 >&3 && exec 3>&-
nc -l localhost 8888 <(cat fifo) > fifo
nc -l localhost 8888 < fifo > fifo
現在我希望這 4 個指令能做同樣的事情,至少最後兩個指令能做同樣的事情。
- 第一個命令的行為符合預期,是一個簡單的回顯伺服器,當客戶端關閉連線時它會關閉。
- 行為類似於 1。
- 我可以連接到伺服器,發送數據,但我從未收到任何回應。當我關閉客戶端連線時,伺服器將關閉。
- 無法連接到伺服器,伺服器永遠監聽。
答案1
這裡的關鍵是開啟 FIFO 是一個阻塞操作。只有open
當兩端都連接時,即一旦 fifo 打開以供讀取和寫入時,才會返回。
Normally, opening the FIFO blocks until the other end is opened also.
在第一種情況下,shell 分叉來執行管道,因此打開 fifo 進行讀取 ( cat fifo
) 和打開 fifo 進行寫入 ( > fifo
) 發生在不同的進程中,因此獨立發生。
在第二種情況下,讀取開啟和寫入開啟 ( 3<>fifo
) 在一個步驟中發生。
在第三種情況下,<(cat fifo)
擴展為檔案名,例如/dev/fd/42
.所以就像你在跑步一樣nc -l localhost 8888 /dev/fd/42 > fifo
。您需要額外的內容<
才能使其等效,例如 nc -l localhost 8888 < <(cat fifo) > fifo
.
在第四種情況下,shell 嘗試開啟 fifo 進行讀取 ( < fifo
) 並開啟它進行寫入 ( > fifo
) 作為相同進程的一部分。 shell 從左到右一次執行一個操作。因此它嘗試打開fifo
以供讀取,並永遠阻塞,等待某些內容打開fifo
以進行寫入。我想你會發現在這種情況下,nc
甚至從未開始,並且端口從未打開用於監聽。