In herkömmlichen Unix-Systemen gibt es keine einfache Möglichkeit, Dateien auszutauschen. Daher müssen Sie einen temporären Zwischennamen verwenden. Stellen Sie aus Gründen der Robustheit sicher, dass der temporäre Name von keinem anderen Programm verwendet wird (verwenden Sie ihn also mktemp
) und dass er sich im selben Dateisystem wie eine der Dateien befindet (andernfalls würden die Dateien unnötig kopiert, anstatt nur umbenannt zu werden).
swap_files () {
tmp_name=$(TMPDIR=$(dirname -- "$1") mktemp) &&
mv -f -- "$1" "$tmp_name" &&
mv -f -- "$2" "$1" &&
mv -f -- "$tmp_name" "$1"
}
swap_files file file_1
Beachten Sie, dass im Falle eines Fehlers die erste Datei möglicherweise noch unter ihrem temporären Namen steht und die zweite Datei möglicherweise noch nicht verschoben wurde. Wenn Sie bei Unterbrechungen und Abstürzen Robustheit benötigen, ist es möglicherweise einfacher, eine Variante mit zwei temporären Namen wiederherzustellen.
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"
}
Wenn die temporären Verzeichnisse .swap_files.????????????
bei einem Neustart vorhanden sind, bedeutet dies, dass ein Dateiaustausch durch einen Stromausfall unterbrochen wurde. Beachten Sie, dass möglicherweise eine der Dateien bereits verschoben wurde und die andere nicht, sodass der Code hier nicht alle Fälle berücksichtigt. Dies hängt davon ab, welche Art von Wiederherstellung Sie wünschen.
Moderne Linux-Kernel (seit 3.15, veröffentlicht im Juni 2014) haben einen Systemaufruf zum Austauschen von Dateien : renameat2(…, RENAME_EXCHANGE)
. Es scheint jedoch kein allgemein verfügbares Befehlszeilenprogramm dafür zu geben. Sogar Glibc-Unterstützung wurde erst kürzlich hinzugefügt ( 2.28 , veröffentlicht im August 2018).