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