Zsh

在 zsh 中,cat <(cat) 與 cat | 之間的區別貓對貓=(貓)?

  • August 25, 2018

我期望cat &lt;(cat)cat | cat做同樣的事情:將行從標準輸入複製到標準輸出。我的理解是,兩者都會cat在子shell 中執行 a ,將 subshel​​lcat的 stdout 重定向到臨時命名管道,然後cat在目前 shell 中執行另一個,並將其 stdin 重定向到管道。

相反,cat &lt;(cat)讓我在終端輸入,但沒有輸入行被複製並且^D無法發出信號EOFcat | cat雖然按預期工作。

作為進一步的實驗,我檢查了是否cat =(cat)有與 類似的困難cat &lt;(cat),但它按我的預期工作:所有標準輸入到 a^D都被一次性複製到標準輸出。

誰能幫我理解 zsh 在幕後做了什麼?

  1. a | b只需STDOUT使用. a_ _ _ 兩個命令並行執行。STDIN``bdup/dup2
  2. a =(b)``a用臨時文件名替換參數 to 。b將在之前執行,a因為需要創建臨時文件才能將其傳遞給a
  3. a &lt;(b)``a用命名管道替換參數。ab並行執行。現在這有點複雜:

b在後台,無法從終端讀取。您可以自己測試它,方法是使用strace -p $PID附加到您的第二個 cat 程序以查看該程序。

a同時嘗試從命名管道讀取,但無法讀取任何內容,因為b無法讀取。

• 這意味著您基本上遇到了死鎖,a嘗試讀取bb無法讀取STDIN且無法寫入a

來自man bash的有關後台程序和終端的更多資訊:

為了便於實現作業控制的使用者界面,作業系統維護了目前終端程序組 ID的概念。此程序組的成員(程序組 ID 等於目前終端程序組 ID 的程序)接收鍵盤生成的信號,例如 SIGINT。據說這些程序處於前台背景程序是那些程序組 ID 與終端不同的程序;這樣的過程不受鍵盤生成的信號的影響。只允許前台程序讀取,或者,如果使用者使用 stty tostop 指定,則寫入終端。嘗試從終端讀取(當 stty tostop 生效時寫入)終端的後台程序由核心的終端驅動程序發送一個**SIGTTIN (SIGTTOU)**信號,除非被擷取,否則它將掛起該程序。

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