Verwenden Sie inotifywait, um Dateien zu verschieben, wenn sie in den Dropbox-Ordner geladen werden

11

Ich versuche einen Weg zu finden, eine Datei sofort in einen anderen Ordner zu verschieben, sobald sie in meiner Dropbox unter CentOS angezeigt wird.

Ich habe das Internet nach Hinweisen durchsucht, aber ich komme nicht weiter als bis zur Tatsache, dass ich inotifyein Skript aufrufen muss, das die Datei so verarbeitet, wie sie angezeigt wird.

Meine BASH-Kenntnisse sind sehr begrenzt und ich bezweifle, dass ich dies in PHP schreiben kann.

Mit anderen Worten, wie kann ich eine Datei in einen anderen Ordner verschieben, sobald sie mit angezeigt wird inotify?

Ortix92
quelle
Ist der Name der Datei konsistent vorhersehbar? Oder ist es Standort? Weitere Details wären hilfreich ...
Jasonwryan
@jasonwryan Es ist ein Dropbox-Ordner, daher ist der Speicherort konsistent. Dies gilt für alle Dateien, die in diesem Ordner abgelegt werden.
Ortix92

Antworten:

13

Dies ist ein einfacher Ansatz:

#!/usr/bin/env bash

dir=/home/ortix/Dropbox/new/
target=/home/ortix/movedfiles/

inotifywait -m "$dir" --format '%w%f' -e create |
    while read file; do
        mv "$file" "$target"
    done

Mit weiteren Details zu den Dateitypen, die Sie verschieben möchten, können Sie Überprüfungen, Protokollierungen usw. hinzufügen.

Jasonwryan
quelle
Ich konnte keine der vorgeschlagenen Antworten testen. Die Dinge kamen auf. Werde das so schnell wie möglich tun! Ich habe allerdings eine Frage. Wenn ich dies in eine Bash-Datei einfügen und ausführen würde, gehe ich davon aus, dass es im Hintergrund ausgeführt wird, richtig? Ich habe immer das Gefühl, dass ein Skript einmal ausgeführt wird, aber hier läuft inotifywait weiter, richtig?
Ortix92
2
Das Abhören eines createEreignisses ist nicht korrekt, da Sie mveine Datei bearbeiten, die möglicherweise nicht vollständig auf die Festplatte kopiert wurde. Siehe @ Gilles Antwort, stattdessen close_writeEreignis verwenden.
fduff
3
@fduff Gilles Antwort zu sehen ist immer das Richtige ...
jasonwryan
16

Der Befehl gibt inotifywaitjedes Mal eine Nachricht aus, wenn sich der Inhalt des angegebenen Verzeichnisses ändert. Sie müssen das richtige Ereignis auswählen: Nicht wenn die Datei erstellt wird, sondern wenn Dropbox den Download abgeschlossen hat. Ich weiß nicht genau, wie Dropbox funktioniert. Wenn es an seiner endgültigen Stelle in die Datei schreibt, hören Sie sich close_writeEreignisse an. Wenn es in die Datei an einen temporären Speicherort schreibt und sie dann an ihren Platz verschiebt, hören Sie sich moved_toEreignisse an. Übergeben Sie die Optionen -m -qan, inotifywaitdamit sie weiterhin auf Ereignisse warten (standardmäßig wartet sie nur auf das nächste Ereignis) und nur relevante Nachrichten druckt.

cd ~/Dropbox/myfolder
inotifywait -m -q -e close_write --format %f . | while IFS= read -r file; do
  cp -p "$file" /path/to/other/directory
done
Gilles 'SO - hör auf böse zu sein'
quelle
1
Dies schlägt bei Dateien fehl, deren Namen Zeilenumbrüche enthalten. Ich konnte keinen Weg finden, um inotifywaitnullterminierte Dateinamen auszugeben. Das Beste, was ich tun konnte, war, ein Zeichen zu verwenden, das weniger wahrscheinlich als beispielsweise Zeilenumbruch ist %f$'\001', und es -d $'\001'mit while IFS= read -roder zu verwenden xargs.
Bis auf weiteres angehalten.
1
@ TennisWilliamson Ja, inotifywaitdas nervt so. Sie können so etwas wie verwenden //%f, da der Dateiname niemals einen doppelten Schrägstrich enthält, solange der zu überwachende Pfad dies nicht tut. dann ist der Ärger auf der Parsing-Seite.
Gilles 'SO - hör auf böse zu sein'