Dateien unter Linux Verschieben

Stevi

Member
Registriert
18 Juli 2018
Beiträge
164
Moin zusammen,

ich stehe gerade vor folgendem Problem:

Ich möchte Dateien unter Linux per Script von einer Ordnerstruktur in eine andere verschieben, dabei soll die Ordnerstruktur beibehalten werden.

Es wird von einem Scanner auf eine Netzwerkfreigabe "Input\A\1" oder "Input\B\2" oder "Input\C\1\XY" usw. eingescannt. Nun sollen die PDF Dokumente von z.B. "Input\A\1\xyz.pdf" nach "work\A\1\xyz.pdf" alle 60 Sekunden verschoben werden, damit Tesseract drüber laufen kann.

Grundsätzlich hat das mit folgendem Script funktioniert: (Das Script läuft von morgens bis Abends in Dauerschleife und wird um 00:10 per Crontab noch mal gestartet)

Code:
#!/bin/bash
while /bin/true; do

        start_date=$(date "+%d-%m-%Y")
        current_date=$start_date
        
        while [ "$start_date" = "$current_date" ]; do
                sleep 1m
                        
                cp -r /mnt/ocr/input/* /mnt/ocr/tesseractwork/
                find /mnt/ocr/input -name '*.pdf' -delete
                    
                /home/xyz/OCRmyFiles.sh
                current_date=$(date "+%d-%m-%Y")
        done
done
exit

Problem hierbei ist das es doch häufiger vorkommt das genau in dem Moment gescannt wird, während der cp Befehl läuft und dann der Löschbefehl. Somit wurde das PDF Dokument noch nicht verschoben aber im nächsten Schritt schon gelöscht.

Das gleiche Passiert wenn ich die Dateien gar nicht in ein "work" Folder für tesseract kopiere, wenn tesseract läuft und es kommt ein neues PDF Dokument vom Scanner, wird am Ende von tesseract auch das Dokument gelöscht. Daher mein Ansatz mit dem work Folder.

Vlt. hat ja jemand eine Idee wie sich das ohne großen Aufwand realisieren lässt? Am besten wäre ein mv Befehl. Hier scheitert es aber daran das die Ordnerstruktur mit allen Unterordnern beibehalten werden muss.
 
Ohne es selbst ausprobiert zu haben kommt mir mein Lieblingstool für solche Dinge in den Kopf.

rsync mit --remove-source-files.

Also in etwa

rsync -avhn --remove-source-files source/ dest/


JETZT komme ich mir aber vor wie ein Mann mit einem Hammer für den jedes Problem ein Nagel ist...
 
hm daran hätte ich auch selbst denken können :facepalm: war so in das Problem vertieft das mir rsync nicht eingefallen ist. Danke, ich tüftle damit mal ein wenig.
 
Hier gehn ein paar Begriffe durcheinander. Du sprichst von Verschieben (was ein schwammiger Begriff ist), und führst dabei eine Kopieroperation durch. Saubere Terminologie ist in diesem Kontext wichtig.
Ich nehme mal an, dass /mnt/ocr/input/ und /mnt/ocr/tesseractwork/ auf verschiedenen Dateisystemen liegen. Damit wird jede Verschiebeoperation zwischen diesen Verzeichnissen zwangsläufig zur Kopieroperation.

Dein Problem ist eine klassische Race Condition. Die Zeit die dein Scanner benötigt um eine Datei anzulegen (Inode reservieren und Inhalt schreiben) ist >0. In dieser Zeit kommt möglicherweise dein Script vorbei, kopiert die noch unvollständige Datei und löscht anschließend ohne Prüfung(!) die Quelle.
rsync --remove-source-files ist hier eher ein Workaround als eine Lösung, denn es verhindert zwar, dass unvollständig übertragene Dateien gelöscht werden, aber das eigentliche Problem ist, dass überhaupt versucht wird, unvollständige Dateien zu kopieren.
Um das zu lösen kannst du neu gescannte Dateien zunächst mit einem temporären Dateinamen anlegen und nach erfolgreichem Scan die fertige Datei dann an ihre endgültige Stelle verschieben. Hier wird auch die Terminologie zwischen Verschieben und Kopieren wieder wichtig: Dieses Verschieben vom tempörären auf den endgültigen Dateinamen muss auf dem selben Dateisystem geschehen, denn dann ist ein Verschieben nur eine Umbenennung bei der keine Daten bewegt werden, sondern nur der Eintrag im Dateisystem-Header geändert wird.* Dieses Umbenennen passiert (nahezu) instantan und schleißt damit Race-Conditions aufgrund einer Kopieroperation (nahezu) aus.


*) Hintergrundinfo: Dateinamen gehören in Wahrheit nicht zur Datei sondern zum Dateisystem, denn sie sind nur Zeiger auf Inodes.
 
Hallo hikaru, danke für deinen Einwand.

beide Pfade liegen auf der gleichen Netzwerkfreigabe. Diese wiederum liegt auf einem Windows Server.

Tesseract (OCR-Erkennung) läuft auf einem Linux Server und greift auf diese Netzwerkfreigaben zu.

Im Grunde ist es egal ob der Windows Server die Dateien verschiebt oder der Linux Server. Ich bin mir aber nicht sicher ob hier wirklich der Scanner unfertige PDF Dateien erstellt. Bisher war ich der Meinung das der Scanner die Datei vollständig in einem schreibt.

Denkbar wäre nun auf dem Windows Server eine Batch Datei zu schreiben, die nur Dateien verschiebt, welche älter als 1 Minute sind. Damit sollte ich das Problem umgehen können.
 
In den Man Pages steht etwas über kopieren/löschen von "unfertigen" Dateien. Offenbar checkt rsync Timestamp/Größe vor dem Löschen. Damit hätte man das Problem von unvollständigen Dateien im Ziel aber einen Datenverlust sollte damit verhindert werden können oder so...

Ansonsten, wenn es Windows Server ist würde ich nach Robocopy schauen. Im Gegensatz zu *nix ist Windows sehr restriktiv was den Zugriff anbelangt. Offene Dateien können z.B. nicht gelöscht werden was unter *nix ein normaler Vorgang ist. Auch kann es Änderungen überwachen, sprich es muss nicht auf Verdacht laufen sondern wartet auf neue Dateien.
 
ich versuche es mal mit einem Batch Script auf dem Windows Server, in der Hoffnung die Probleme zu umgehen.

Code:
ROBOCOPY "%source%" "%destination%" /MOV /W:1 /R:10 /MT:10 /XJD /XJF /MOT:1 /E /TEE

Dabei wird mittels /MOV das Verzeichnis auf Veränderungen überwacht. /MOT:1 führt die Prüfung alle 1 Minute durch. /E führt /MOV anscheinend auch für Unterverzeichnisse aus.
 
Aehm, warum schreibst du die Dateien nicht gleich dort hin wo sie hingehören, statt sie dort hin zu verschieben?
 
Tesseract läuft alle 60 Sekunden. Es nimmt sich die PDF-Dokumente aus dem Input Folder, bearbeitet diese (OCR) und verschiebt diese in das Output Folder.
Wenn währen diesem Durchlauf weitere PDF-Dokumente in den Input Folder abgelegt werden, werden diese in dem OCR-Durchlauf nicht mehr berücksichtigt, aber von Tesseract gelöscht.
D.h. Tesseract "cached" die Dateien pro Durchlauf und löscht am Ende alle PDF-Dateien im Input Ordner. egal ob diese tatsächlich schon bearbeitet wurden oder nicht und zwischenzeitlich neu dazu kamen.

und genau das kommt häufiger vor als ich anfangs dachte.
 
Warum machst du das dann nicht mit inotifywait? z.B.:

Code:
#!/bin/bash
inotifywait -m /wo/die/daten/liegen | grep CLOSE | while read a; do mv $a /da/wo/das/hin/soll/; done
 
Danke für den Hinweis, inotifywait höre ich das erste mal und schaue ich mir an :)

Problem wird vermutlich die Ordnerstruktur sein:

INPUT/A/123 -> OUTPUT/A/123
INPUT/A/456 -> OUTPUT/A/456
INPUT/A/789 -> OUTPUT/A/789
 
Ok, ordner ...
Code:
#!/bin/bash inotifywait -r -m /wo/die/daten/liegen | grep --invert-match ISDIR | grep CLOSE | while read a; do 
  mkdir -p /da/wo/das/hin/soll/$(dirname $a)
  mv $a /da/wo/das/hin/soll/$(dirname $a)
  rmdir $(dirname $a) 
done
 
irgendwie scheint es noch nicht so recht zu klappen. Zwar startet inotifywait, erkennt aber nicht wenn ich neue Dateien in input schiebe.

Code:
inotifywait -r -m /mnt/ocr/input | grep --invert-match ISDIR | grep CLOSE | while read a; do
                mkdir -p /mnt/ocr/tesseractwork/$(dirname $a)
                mv $a /mnt/ocr/tesseractwork/$(dirname $a)
                rmdir $(dirname $a)

                /home/<sshuser>/OCRmyFiles.sh
done
 
/mnt/ocr ist nicht zufällig ein FAT Dateisystem oder eine windows Share?
 
ja ist es. (Windows Share) Geht damit nicht, oder?
 
Zuletzt bearbeitet:
habe ich nun auch ausprobiert. Leider scheint das Script noch einen Fehler zu haben. Inotifywait bekommt nicht mit wenn eine neue Datei geschrieben wird.
Starte ich inotifywait manuell, erhalte ich entsprechend die Ausgabe bei Änderungen.
 
Diese Aussage ist nicht schlüssig. Poste mal, was inotify auswirft, vielleicht hat sich ja wieder mal das Format geändert.
 
also wenn ich das Script mit dem von dir genannten Code starte:


Code:
#!/bin/bash

        inotifywait -r -m /home/konicaminolta | grep --invert-match ISDIR | grep CLOSE | while read a; do

                mkdir -p /home/tesseract/$(dirname $a)
                mv $a /home/tesseract/$(dirname $a)
                rmdir $(dirname $a)

                /home/<sshuser>/OCRmyFiles.sh

        done
exit

erhalte ich folgendes:
Code:
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

Kopiere ich dann eine PDF-Datei auf die Netzwerkfreigabe von diesem Linux Server, passiert nichts.

Starte ich inotifywait manuell mit folgendem Befehl:

Code:
inotifywait -r -m /home/konicaminolta

erhalte ich wieder als Rückmeldung:

Code:
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

Kopiere ich eine Datei auf die Netzwerkfreigabe von diesem Linux Server, erscheinen folgende Meldungen:

Code:
...
/home/konicaminolta/Ordner1/Eingang/ ATTRIB S Printe1230123123 - Copy.pdf
...


Erwartet hätte ich das bei oben genanntem Script bei jedem neuen PDF-Dokument dieses in den Ordner /home/tesseract/<Unterordner1>/<Unterordner2>/meinedatei.pdf verschoben wird und das Script unter /home/<sshuser>/OCRmyFiles.sh gestartet wird, sprich die Tesseract OCR Erkennung drüber läuft.

Ich vermute mal das der grep Befehl nicht funktioniert.
 
Zuletzt bearbeitet:
Wieso sollt der Grep-Befehl nicht funktionieren? Das wäre ein veritabler Bug und wäre schon lange im Bugtracker aufgeschlagen.

Kannst du mal den vollständigen Output von inotifywait schicken, und nicht nur eine Teile, wo dir inotifywait die Änderung eines Attributes mitteilt? IMO verstecken sich hinter den "..." mindestens ein paar Meldungen zu Datum geändert, Directory erstellt, Atribute erstellt, Datei geöffnet, datei geschlossen ....
 
  • ok1.de
  • ok2.de
  • thinkstore24.de
  • Preiswerte-IT - Gebrauchte Lenovo Notebooks kaufen

Werbung

Zurück
Oben