traiter les files dans un directory tel qu'ils apparaissent

Duplicata possible:
Comment exécuter une command lorsque le contenu d'un directory est mis à jour?

J'essaie d'écrire un process simple etl qui chercherait des files dans un directory chaque minute, et si oui, les charger sur un système distant (via un script), puis les supprimer.

Des choses qui compliquent cela: le chargement peut prendre plus d'une minute. Pour contourner cela, j'ai pensé que je pouvais déplacer tous les files dans un directory de traitement temporaire, y agir, puis les supprimer de là. En outre, dans ma tentative d'améliorer les scripts en command line, j'essaie d'get une solution plus élégante. J'ai commencé par écrire un script simple pour accomplir ma tâche, montré ci-dessous:

#!/bin/bash for i in ${find /home/me/input_files/ -name "*.xml"}; do FILE=$i; done; BASENAME=`basename $FILE` mv $FILE /tmp/processing/$BASENAME myscript.sh /tmp/processing/$BASENAME other_inputs rm /tmp/processing/$BASENAME 

Ce script supprime presque immédiatement le file du directory de traitement (qui arrête le problème de traitement en double), nettoie après lui-même à la fin et permet le traitement du file entre les deux.

Cependant, c'est U / Linux après tout. J'ai l'printing que je devrais être capable d'accomplir tout cela sur une seule ligne en faisant des passes et en déplaçant les choses au lieu d'un script volumineux à maintenir.

En outre, l'utilisation parallèle au process concurrent ce serait un plus.

Addendum : une sorte de queue FIFO pourrait être la réponse à cela également. Ou peut-être une autre sorte d'observateur de directory au lieu d'un cron. Je suis ouvert à toutes les suggestions plus élégantes que mon petit script. Seul problème est les files dans le "directory d'input" sont touchés des moments avant qu'ils ne soient réellement écrits, donc une sorte de! -size -0 serait nécessaire pour gérer uniquement les files réels.

Il semble que vous devriez simplement écrire un petit script de traitement et utiliser GNU Parallel pour le parallel processing:

http://www.gnu.org/software/parallel/man.html#example__gnu_parallel_as_dir_processor

Donc quelque chose comme ça:

 inotifywait -q -m -r -e CLOSE_WRITE --format %w%f my_dir | parallel 'mv {} /tmp/processing/{/};myscript.sh /tmp/processing/{/} other_inputs; rm /tmp/processing/{/}' 

Regardez les videos d'intro pour en savoir plus: http://pi.dk/1

Modifier:

Myscript.sh doit gérer les files de longueur 0 (par exemple, les ignorer).

Si vous pouvez éviter le touch vous pouvez même faire:

 inotifywait -q -m -r -e CLOSE_WRITE --format %w%f my_dir | parallel myscript.sh {} other_inputs 

L'installation de GNU Parallel est aussi simple que:

 wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel chmod 755 parallel 

Tout d'abord, votre script fonctionnera sur un file (le dernier de la list). Aussi, je ne pense pas qu'un seul liner soit toujours approprié ou élégant. Cron fait beaucoup dans les coulisses, et vous devez être en mesure de revoir les choses qui échouent. Courir cron "fréquemment" peut être un problème. Vous pouvez vous refind avec des dizaines de ces process en cours d'exécution, ralentissant les systèmes car ils tentent tous de traiter les files dans leur queue.

C'est ce que je ferais.

 Dir="$HOME/input_files" # never hardcode when you have variables for filename in "$Dir"/*.xml; do # is the file non-empty AND is it still there, or may caught by another # process if [ -s "$filename" ]; then # move files locally will be faster than crossing filesystems to /tmp mkdir -p "$Dir/.processing" # temp name should use pid, just in case another input with the same name comes in tempname="$Dir/.processing/`basename $filename .xml`.$$" mv "$filename" "$tempname" # send stdout and stderr to a .output file myscript.sh "$tempname" other_inputs > "$tempname.output" 2>&1 rc=$? if [ $rc -eq 0 ]; then rm "$tempname" "$tempname.output" else echo "Error processing $filename; rc=$rc" >&2 echo "File in $tempname" >&2 fi done 

Cela supprimera le file après le traitement ou, en cas d'erreur, conservera le file dans le directory .processing , y compris la sortie de la command. La command ci-dessus n'obtient rien, mais elle permet de faire fonctionner plus d'un sans interférer les uns avec les autres. Il y a d'autres questions sur la façon de créer des files d'attente de travail assez efficaces pour augmenter.

Utilisez l' interface inotify (7) pour surveiller le directory entrant plutôt que d'interroger via cron. inotify-tools vous donne le programme inotifywait que vous pouvez utiliser pour surveiller le directory si vous ne voulez pas écrire de code par rapport à l'interface d'appel du système.