Bash 中重新導向資料的危險性

在 Bash 中,如果你將輸入與輸出的檔案設為同一個,如下列這段程式:

cat test.txt | cut -d '/' -f 3 | sed 's/file/doc/' > test.txt

在跑完之後,也許你會想打開檔案看看,但打開之後,有很高的機率你會發現,該檔案是空的

這是為什麼呢?因為 Bash 基於某種原因,會在跑指令的同時 清空輸出要導向的檔案,這種情況下會產生「競賽條件」(race condition):以上面的指令舉例,如果是 cat test.txt 先被執行,檔案內容就會被保留,但如果 > test.txt 先被執行,檔案就會被清空。在我的經驗中,通常執行這類指令結果都是檔案被淨空,因此還是要先將輸出導向到不同名稱的檔案,再用這個檔案覆蓋過原檔。上面的指令就會變成:

cat test.txt | cut -d '/' -f 3 | sed 's/file/doc/' > test.txt-tmp
mv test.txt-tmp test.txt

—— ltlnx 2024-02-05

標籤:隨想

如果想讓我知道您看過這個頁面,請點擊這個連結運作原理