Ich habe zwei separate Verzeichnisse. Der Benutzer lädt eine Datei in die erste. Im Hintergrund läuft ein Cronjob, der die Dateien alle 5 Minuten in das zweite Verzeichnis kopiert.
Was passiert, wenn der Benutzer seinen Upload nicht abgeschlossen hat und der Cronjob die Dateien kopiert? Beachten Sie, dass die beiden Verzeichnisse unterschiedlichen Benutzern gehören und der Cronjob als Root ausgeführt wird.
cp
Wird nicht warten, bis die Datei vollständig hochgeladen ist. Da wir davon ausgehen, dass die Netzwerkübertragungsrate niedriger ist als das Kopieren der Datei von einem Speicherort zu einem anderen innerhalb desselben Hosts, wirdcp
irgendwann das aktuelle Dateiende erreicht und der Kopiervorgang abgebrochen. Die Lösung Ihres Problems kann einfach sein: Zuerst lädt der Benutzer die Datei mit einem speziell entstellten Dateinamen hoch (z. B. mit vorangestelltem.
Punkt). Wenn die Übertragung abgeschlossen ist, benennt der Benutzer sie in den ursprünglichen Namen um. Dann sieht der Cron-Job nur noch aus für die Dateien, die nicht beginnen mit.
.Antworten:
cp
weiß nicht über geöffnete Dateien. Wenn also der erste Benutzer eine große Datei hochlädt und cronjob (oder ein anderer Prozess) mit dem Kopieren dieser Datei beginnt, wird nur so viel kopiert, wie bereits geschrieben wurde. Auf diese Weise können Sie darüber nachdenken - erstelltcp
eine Kopie dessen, was sich derzeit auf der Festplatte befindet, unabhängig davon, ob die Datei vollständig ist. Andernfalls könnten Sie beispielsweise keine Protokolldateien kopieren.quelle
fuser
+ verwendetcp
. Eine solche Kopie wäre wirklich sehr unzuverlässig. Sie kopiert keine Datei, die zum Beispiel im Texteditor geöffnet wird.lsof
? Die Ausgabe soll einfach zu verarbeiten sein. Sie können die Dateien filtern, diecp
zum Schreiben geöffnet werden (z. B. nach einer Instanz von ).fuser
natürlich auf), da dieses Tool möglicherweise nicht alle Dateien anzeigt.cp
weiß nicht, in welchen anderen Programmen die Dateien möglicherweise geöffnet sind. Da ist keine Magie drincp
. Das Design von Unix vermeidet absichtlich, dass Dateien gesperrt werden, es sei denn, es gibt einen zwingenden Grund (zwingend, der Kernel benötigt ihn). Zu diesem Thema siehe Wendet die Umleitung der Ausgabe in eine Datei eine Dateisperre an?Solche Situationen, in denen eine Datei von einem Produzenten erstellt und, sobald sie vollständig ist, von einem Konsumenten konsumiert wird, sind häufig. Die übliche Vorgehensweise besteht darin, dass der Produzent eine temporäre Datei schreibt, nach der der Konsument nicht sucht. Sobald der Produzent fertig ist, verschieben Sie die Datei an einen Ort, an dem der Konsument sie finden wird. Das Verschieben einer Datei (auf demselben Dateisystem) ist eine atomare Operation: Irgendwann wechselt die Datei für den Konsumenten von "nicht da" zu "da".
Sorgen Sie also dafür, dass Ihr Upload-Auftrag die Dateien nach Abschluss des Uploads in ein anderes Verzeichnis verschiebt. Richten Sie den Cron-Job auf dieses andere Verzeichnis.
quelle
Anscheinend möchten Sie einen Dir-Synchronisierungsjob ausführen.
Weil die Option -u, --update von
cp
Sie können also einen Cronjob hinzufügen,
cp -auv SOURCEDIR/* DESTDIR
der die Dateien kopiert, deren Änderungszeit geändert wurde. Das bedeutet,DESTDIR
dass Sie eventuell die vollständige Kopie erhalten, während der Upload abgeschlossen ist.rsync
kann den gleichen Job machen. zBrsync -av SOURCEDIR/ DESTDIR
.Obwohl die Option -a angewendet wird, können einige angegebene Attribute (z. B. Eigentumsrechte) nur vom Superuser beibehalten werden.
Siehe
man cp
,man rsync
für weitere Einzelheiten.quelle