staging.inyokaproject.org

Datei nur dann lesen, wenn sie nicht mehr geschrieben wird

Status: Ungelöst | Ubuntu-Version: Ubuntu 20.04 (Focal Fossa)
Antworten |

jms3000

Avatar von jms3000

Anmeldungsdatum:
29. Januar 2015

Beiträge: 880

Eine grosse Datei kommt per FTP und wird dann in ein Zielverzeichnis kopiert, wahrscheinlich mit "mv". Ein Programm schaut regelmässig, ob die Datei da ist und wenn ja, wird sie verarbeitet. Wie kann ich sicherstellen, dass die Datei komplett im Zielverzeichnis geschrieben wurde, bevor sie verarbeitet wird? Ich befürchte, dass die Datei schon im Directory auftaucht bevor sie fertig erstellt wurde. Auch wenn das nur Sekunden oder Millisekunden sind, ist es immer ein Risiko. Kann ich vor dem Lesen die Datei irgendwie locken?

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

Kannst du beeinflussen, wie dieser Kopiervorgang stattfindet? Dann könntest du die Datei erst mit .tmp hinten oder so erstellen und dann umbenennen. Dieses Umbenennen ist dann – wenn es auf demselben Dateisystem passiert – atomar. Sprich, wenn du die Datei dann siehst, ist sie sicher komplett da.

1
2
cp /var/ftp/irgendwas-grosses.img /home/foo/irgendwas-grosses.img.tmp     # kann eine Weile dauern
mv /home/foo/irgendwas-grosses.img.tmp /home/foo/irgendwas-grosses.img    # atomar

jms3000

(Themenstarter)
Avatar von jms3000

Anmeldungsdatum:
29. Januar 2015

Beiträge: 880

Vain schrieb:

Kannst du beeinflussen, wie dieser Kopiervorgang stattfindet? Dann könntest du die Datei erst mit .tmp hinten oder so erstellen und dann umbenennen. Dieses Umbenennen ist dann – wenn es auf demselben Dateisystem passiert – atomar. Sprich, wenn du die Datei dann siehst, ist sie sicher komplett da.

Das müsste eigentlich gehen und wäre recht einfach. Danke!

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

So etwas löst man eleganterweise mit inotifywait:

1
2
3
inotifywait -mqre close_write,moved_to --format '%w%f' dir | while read -r file; do
  echo ">> process $file"
done

oder

1
2
3
while file=$(inotifywait -qre close_write,moved_to --format '%w%f' dir); do
  echo ">> process $file"
done

jms3000

(Themenstarter)
Avatar von jms3000

Anmeldungsdatum:
29. Januar 2015

Beiträge: 880

rklm schrieb:

So etwas löst man eleganterweise mit inotifywait:

Interessant...danke!

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Noch ein Hinweis: die zweite Lösung hat eine Race Condition: wenn weitere Dateien geschrieben oder verschoben werden, während eine bearbeitet wird, werden die nicht erfasst. Die erste Lösung hat das Problem nicht.

jms3000

(Themenstarter)
Avatar von jms3000

Anmeldungsdatum:
29. Januar 2015

Beiträge: 880

rklm schrieb:

Noch ein Hinweis: die zweite Lösung hat eine Race Condition: wenn weitere Dateien geschrieben oder verschoben werden, während eine bearbeitet wird, werden die nicht erfasst. Die erste Lösung hat das Problem nicht.

Das ist aber nur wegen dem "dir"?

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

jms3000 schrieb:

rklm schrieb:

Noch ein Hinweis: die zweite Lösung hat eine Race Condition: wenn weitere Dateien geschrieben oder verschoben werden, während eine bearbeitet wird, werden die nicht erfasst. Die erste Lösung hat das Problem nicht.

Das ist aber nur wegen dem "dir"?

Nein, damit hat das nix zu tun.

Antworten |