我一直工作在這一段時間,似乎是沒有辦法做到這一點與過程替代,除了訴諸內嵌信號,並能真的只能用於輸入管道,所以我不打算擴展它。
但是,bash-4.0提供了coprocesses,它可以用來取代在這種情況下的進程替換,並提供清晰的收穫。
你提供下面的代碼片段:
git status --short | tee >(xargs -Istr test -z str)
可以通過東西都被替換爲:
coproc GIT_XARGS { xargs -Istr test -z str; }
{ git status --short | tee; } >&${GIT_XARGS[1]}
exec {GIT_XARGS[1]}>&-
wait ${GIT_XARGS_PID}
現在,對於一些解釋:
的coproc
調用創建一個新的協進程,命名它GIT_XARGS
(你可以使用任何你喜歡的名字),並運行大括號中的命令。爲協處理創建了一對管道,重定向其標準輸入和標準輸出。
的coproc
調用設置兩個變量:
${GIT_XARGS[@]}
含有管道處理stdin和stdout,適當地([0]
從標準輸出讀,[1]
寫入標準輸入),
${GIT_XARGS_PID}
含有協進程PID。
然後,運行命令並將其輸出定向到第二個管道(即coprocess的stdin)。看似隱祕的>&${GIT_XARGS[1]}
部分擴展到>&60
這是常規的輸出到fd重定向。
請注意,我需要把你的命令放在大括號中。這是因爲管道會導致子進程生成,並且它們不會從父進程繼承文件描述符。換句話說,執行以下操作:
git status --short | tee >&${GIT_XARGS[1]}
會失敗,無效的文件描述符錯誤,因爲相關的FD的父進程存在,而不是催生tee
過程。將其放在大括號中會導致bash將重定向應用於整個管道。
exec
調用用於關閉到您的協處理的管道。在使用進程替換時,該進程會作爲輸出重定向的一部分生成,並且在重定向不再生效後立即關閉該進程的管道。由於協處理管道的生命週期超出了單個重定向,我們需要明確地關閉它。
關閉輸出管道應該會導致進程在標準輸入上獲得EOF條件並正常終止。我們使用wait
等待終止並收穫。 wait
返回協處理器的退出狀態。
作爲最後一個注意事項,請注意,在這種情況下,您不能使用kill
來終止協處理,因爲這會改變其退出狀態。
對不起,你究竟想要達到什麼目的?只需檢查該目錄中是否有git狀態? –
是的,它是部署腳本的一部分,如果目錄很髒,應該退出非零值。 – jodell