Solange Sie die Datei nicht über Dateisystemgrenzen hinweg verschieben, sollte der Vorgang sicher sein. Dies ist auf den Mechanismus zurückzuführen, wie »Bewegen« tatsächlich durchgeführt wird.
Wenn Sie mv
eine Datei auf demselben Dateisystem haben, wird die Datei nicht wirklich berührt, sondern nur der Dateisystemeintrag wird geändert.
$ mv foo bar
macht eigentlich sowas
$ ln foo bar
$ rm foo
Dies würde einen schaffen harten Link (ein zweiter Verzeichniseintrag) für die Datei (eigentlich die Inode wies nach Dateisystemeintrag) foo
genannt bar
und das Entfernen foo
Eintrag. Da es jetzt beim Entfernen foo
einen zweiten Dateisystemeintrag gibt, der auf foo
den Inode verweist , werden durch das Entfernen des alten Eintrags foo
tatsächlich keine Blöcke entfernt, die zum Inode gehören.
Ihr Programm würde die Datei trotzdem gerne anhängen, da sein offenes Dateihandle auf den Inode der Datei und nicht auf den Dateisystemeintrag verweist.
Hinweis: Wenn Ihr Programm die Datei zwischen den Schreibvorgängen schließt und erneut öffnet, wird am Ende eine neue Datei mit dem alten Dateisystemeintrag erstellt!
Dateisystemübergreifende Verschiebungen:
Wenn Sie die Datei über Dateisystemgrenzen hinweg verschieben, werden die Dinge hässlich. In diesem Fall können Sie nicht garantieren, dass Ihre Datei konsistent bleibt, da mv
dies tatsächlich der Fall wäre
- Erstellen Sie eine neue Datei auf dem Zieldateisystem
- Kopieren Sie den Inhalt der alten Datei in die neue Datei
- entferne die alte Datei
oder
$ cp /path/to/foo /path/to/bar
$ rm /path/to/foo
bzw.
$ touch /path/to/bar
$ cat < /path/to/foo > /path/to/bar
$ rm /path/to/foo
Je nachdem, ob der Kopiervorgang während des Schreibens Ihrer Anwendung das Dateiende erreicht, kann es vorkommen, dass die neue Datei nur eine halbe Zeile enthält.
Wenn Ihre Anwendung die alte Datei nicht schließt und erneut öffnet, wird weiterhin in die alte Datei geschrieben, auch wenn sie gelöscht zu sein scheint: Der Kernel weiß, welche Dateien geöffnet sind, und obwohl der Dateisystemeintrag gelöscht wird, wird er gelöscht Löscht den Inode und die zugehörigen Blöcke der alten Datei erst, wenn die Anwendung das geöffnete Datei-Handle schließt.
rename()
Systemaufruf. Die ursprüngliche Version von hat alsomv
tatsächlich aufgerufenlink()
, um den festen Link zu erstellen, und anschließendunlink()
den ursprünglichen Namen zu entfernen.rename()
wurde in FreeBSD hinzugefügt, um dies atomar im Kernel zu implementieren.