Shell

交換文件名的最佳方法

  • January 3, 2022

我需要交換兩個文件(filefile_1)的文件名。我正在使用以下程式碼。

mv file .phfile
mv file_1 file
mv .phfile file

這可行,但非常有問題,有時甚至會導致數據失去。有一個更好的方法嗎?

Linux系統上的renameat2系統呼叫,帶有RENAME_EXCHANGE標誌,應該做到這一點,是一個聲稱使用它的cli工具。

在傳統的 Unix 系統中沒有交換文件的低級方法,因此您需要使用中間臨時名稱。為了穩健,請確保臨時名稱不會被任何其他程序使用(所以使用mktemp),並且它與其中一個文件位於同一文件系統上(否則這些文件將被不必要地複製而不是被重命名)。

swap_files () {
 tmp_name=$(TMPDIR=$(dirname -- "$1") mktemp) &&
 mv -f -- "$1" "$tmp_name" &&
 mv -f -- "$2" "$1" &&
 mv -f -- "$tmp_name" "$2"
}
swap_files file file_1

請注意,如果發生錯誤,第一個文件可能仍使用其臨時名稱,而第二個文件可能尚未移動,也可能尚未移動。如果您需要在中斷和崩潰的情況下保持穩健性,具有兩個臨時名稱的變體可能更容易從中恢復。

swap_files2 () {
 tmp_dir1=$(TMPDIR=$(dirname -- "$1") mktemp -d .swap_files.XXXXXXXXXXXX) &&
 tmp_dir2=$(TMPDIR=$(dirname -- "$2") mktemp -d .swap_files.XXXXXXXXXXXX) &&
 mv -f -- "$1" "$tmp_dir1/" &&
 mv -f -- "$2" "$tmp_dir2/" &&
 mv -f -- "$tmp_dir1/"* "$1" &&
 mv -f -- "$tmp_dir2/"* "$2" &&
 rmdir -- "$tmp_dir1" "$tmp_dir2"
}

如果重新啟動時出現臨時目錄.swap_files.????????????,則意味著文件交換因電源故障而中斷。請注意,其中一個文件可能已經移動到位而另一個文件沒有,因此這裡的程式碼並不能處理所有情況,這取決於您想要什麼樣的恢復。

現代 Linux 核心(自 3.15 起,於 2014 年 6 月發布)具有交換文件的系統呼叫:renameat2(…, RENAME_EXCHANGE). 但是,似乎沒有一個常用的命令行實用程序。甚至 glibc 支持也是最近才添加的(2.28,於 2018 年 8 月發布)。

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