Wie geht "cp" mit offenen Dateien um?

15

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.

Stickig
quelle
Bitte lesen Sie diesen Beitrag, um zu sehen, was in einem solchen Fall passiert: unix.stackexchange.com/questions/49299/…
Serge
Danke, guter Beitrag, den du geschrieben hast. Aber meine Frage bezog sich eher auf cp, nicht auf die Handhabung von Linux-Dateien im Allgemeinen. Vielleicht prüft cp, ob die Datei noch offen ist und wartet, bis sie geschlossen ist oder so.
Stuffy
Nr. cpWird 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, wird cpirgendwann 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 ..
Serge

Antworten:

17

cpweiß 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 - erstellt cpeine 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.

Krzysztof Adamski
quelle
Danke, das wollte ich wissen! Gibt es eine einfache Möglichkeit, dies zu vermeiden? Ich habe die Manpage von cp durchgesehen, aber nichts Nützliches gefunden.
Stuffy
Um was genau zu machen? Alle Dateien außer den offenen kopieren? Ich denke, es gibt keine einfache Möglichkeit, dies zu tun (außer das Schreiben eines eigenen Skripts, das fuser+ verwendet cp. Eine solche Kopie wäre wirklich sehr unzuverlässig. Sie kopiert keine Datei, die zum Beispiel im Texteditor geöffnet wird.
Krzysztof Adamski
@Stuffy, vielleicht könntest du in deinem Cronjob offene Dateien mit auflisten lsof? Die Ausgabe soll einfach zu verarbeiten sein. Sie können die Dateien filtern, die cpzum Schreiben geöffnet werden (z. B. nach einer Instanz von ).
Wojtek Rzepala
@WojtekRzepala, ich schaue mir das an, danke. Vielleicht schreibe ich ein kleines Skript, das vom Cronjob ausgeführt wird
Stuffy
@Stuffy: Denken Sie daran, dass es möglicherweise nicht wirklich zuverlässig ist, wenn es nicht vom Root-Benutzer ausgeführt wird (das gleiche Problem tritt fusernatürlich auf), da dieses Tool möglicherweise nicht alle Dateien anzeigt.
Krzysztof Adamski
7

cpweiß nicht, in welchen anderen Programmen die Dateien möglicherweise geöffnet sind. Da ist keine Magie drin cp. 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.

Gilles 'SO - hör auf böse zu sein'
quelle
6

Anscheinend möchten Sie einen Dir-Synchronisierungsjob ausführen.

Weil die Option -u, --update voncp

Kopieren Sie nur, wenn die SOURCE-Datei neuer als die Zieldatei ist oder wenn die Zieldatei fehlt

Sie können also einen Cronjob hinzufügen, cp -auv SOURCEDIR/* DESTDIRder die Dateien kopiert, deren Änderungszeit geändert wurde. Das bedeutet, DESTDIRdass Sie eventuell die vollständige Kopie erhalten, während der Upload abgeschlossen ist.

rsynckann den gleichen Job machen. zB rsync -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 rsyncfür weitere Einzelheiten.

Edw4rd
quelle
Achten Sie nur darauf, dass Sie sich nicht auf die neuesten Einträge im Zielordner verlassen - es handelt sich möglicherweise nicht um vollständige Dateien.
dubiousjim