當在fish shell中執行這些命令時
$ mkfifo answer
$ nc -vv -l -k -p 8001 <answer | tee -a answer
該命令掛起。
如果我通過echo "" > answer寫到answer。然后,nc恢復并開始正確地收聽。
如果與此相反,我CTRL-C了掛起的行程,下面是訊息:
^C<W> fish: 發生了一個錯誤 while redirecting file 'answer'。
打開。被中斷的系統呼叫
另一方面,在bash中,當執行:
時$ mkfifo answer
$ nc -vv -l -k -p 8001 <answer | tee -a answer
在本地主機8001上監聽
該命令沒有掛起并直接開始監聽。
在fish和bash中發生了什么不同的情況來解釋這種不同的行為呢?
uj5u.com熱心網友回復:
關鍵的區別是fish在父shell的fork之前打開重定向的檔案,而bash則在fork之后,在子行程中進行。
當你為讀打開一個命名的管道時,打開的呼叫將阻塞,直到有一個相應的寫者(反之亦然)。你的管道同時包含了讀者和寫者,但要求相應的打開呼叫在子行程中并行發生。在fish中,nc在檔案被打開之前無法啟動,所以你會得到一個死鎖。
一種解決方法是安排一個子行程自己打開檔案,而不是使用重定向。例如,這將避免出現死鎖:
cat answer | nc -vv -k -l -p 8001 | tee -a answer
fish之所以有這樣的行為,是因為它也使用了執行緒,這限制了你在分叉的子程式中可以做什么。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/324970.html
標籤:
上一篇:根據一個值對12行的組進行排序
下一篇:在bash中停止一個背景回圈
