我需要能夠重定向輸出到一個文件,並檢查KSH腳本的返回代碼(不能使用pipestatus或pipefail),我找到了一個解決方案,但我不確定文件描述符4的意義是什麼,有人可以解釋一下嗎?輸出文件描述符重定向
{
rc=$(
{
{
. somescript.sh 2>&1
echo "$?" >&3
} | tee -a somefile.txt
} 3>&1 >&4 4>&-
)
} 4>&1
echo "${rc}"
我需要能夠重定向輸出到一個文件,並檢查KSH腳本的返回代碼(不能使用pipestatus或pipefail),我找到了一個解決方案,但我不確定文件描述符4的意義是什麼,有人可以解釋一下嗎?輸出文件描述符重定向
{
rc=$(
{
{
. somescript.sh 2>&1
echo "$?" >&3
} | tee -a somefile.txt
} 3>&1 >&4 4>&-
)
} 4>&1
echo "${rc}"
rc=$(...)
意味着該返回碼將是任何由(...)
內的代碼印刷在文件描述符(FD)1
。所以,不知何故,somescript.sh
輸出必須被移出fd 1
,然後再回來。 echo
行輸出somescript.sh
的返回碼爲fd 3
。然後,3>&1
將保存的返回碼發送到fd 1
,其中$(...)
預計它。然而,這意味着舊的fd 1
(從{somescript 2>&1 } | tee
)沒有任何可去的地方。所以舊的fd 1
被重定向到fd 4
與>&4
(並且由於輸入側不會被使用,所以輸入側被關閉了4>&-
)。然後,一旦$(...)
結束,最後的4>&1
將somescript|tee
的輸出放回到其他程序期望它的fd 1
處。
Whe!
沒有>&4
的somescript.sh
輸出和echo "$?"
輸出將上因爲3>&1
的FD 1
混合。因此,fd 4
是在使用fd 1
來執行返回碼期間的實際輸出somescript.sh
的等待筆。
如果你願意使用命名管道,可以與所有的文件描述符角力分配:
mkfifo p
tee -a somefile.txt < p &
. somescript.sh > p
rc=$?
在這裏,我們在後臺運行tee
,讓它從命名管道讀取其輸入p
。一旦該作業開始,我們就會獲取腳本並將其輸出重定向到命名管道。腳本完成後,您可以使用普通的賦值語句將其退出狀態保存到rc
。這也將關閉管道的殼端,這將導致另一端也關閉,並允許退出tee
。
我一直認爲$(...)是從stdout讀取的,這也是fd 1通常指向的內容,但是如果它從fd 1讀取,那麼這會很有意義。謝謝。 – dood
fd 1不「指向」標準輸出;它*是*標準輸出。 – chepner
@chepner啊好的,謝謝你的澄清,然後通常stdout指向終端。 – dood