Ich muss die Dateinamen von zwei Dateien ( file
und file_1
) austauschen . Ich benutze den folgenden Code dafür.
mv file .phfile
mv file_1 file
mv .phfile file
Dies funktioniert, ist aber sehr fehlerhaft. Manchmal führt es sogar zu Datenverlust. Gibt es einen besseren Weg, dies zu tun?
shell
shell-script
files
rename
Binoy Babu
quelle
quelle
Antworten:
Der
renameat2
Syscall auf Linux-Systemen mit demRENAME_EXCHANGE
Flag sollte genau das tun. Dies ist ein CLI-Tool, das behauptet, es zu verwenden.quelle
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).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.
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).quelle
Folgendes habe ich letztendlich verwendet:
quelle
Das ist robuster:
Das Zitieren dient dazu, Probleme mit Leerzeichen in Dateinamen zu vermeiden. Es verwendet eine tmp-Datei und && führt den folgenden Befehl nur aus, wenn der vorhergehende erfolgreich beendet wurde.
quelle
file1=1stfile && file2=2ndfile && temp="$(mktemp -dp /mnt/sdcard)" && mv "$file1" $temp && mv "$file2" "$file1" && mv $temp/"$file1" "$file2"
. Es klappt. Danke für deinen Beitrag.