Utilisez inotifywait pour déplacer le fichier lorsqu'il se charge dans le dossier de la boîte de dépôt

12

J'essaie de trouver un moyen de déplacer immédiatement un fichier vers un autre dossier dès qu'il apparaît dans ma boîte de dépôt sur CentOS.

J'ai parcouru Internet pour trouver des indices mais je ne peux pas aller plus loin que le fait que je doive utiliser inotifypour invoquer un script qui traitera le fichier tel qu'il apparaît.

Mes connaissances BASH sont très limitées et je doute que je puisse écrire ceci en PHP.

En d'autres termes, comment puis-je déplacer un fichier vers un autre dossier dès qu'il apparaît en utilisant inotify?

Ortix92
la source
Le nom du fichier est-il toujours prévisible? Ou son emplacement? Plus de détails seraient utiles ...
jasonwryan
@jasonwryan C'est un dossier dropbox donc l'emplacement est cohérent. Et cela s'applique à tout fichier déposé dans ce dossier.
Ortix92

Réponses:

13

Il s'agit d'une approche simple:

#!/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

Avec plus de détails sur les types de fichiers que vous souhaitez déplacer, vous pouvez ajouter quelques vérifications, journalisation, etc.

jasonwryan
la source
Je n'ai pu tester aucune des réponses suggérées. Les choses ont surgi. Le fera dès que possible! Par contre, j'ai une question. Si je devais mettre cela dans un fichier bash et l'exécuter, je suppose qu'il s'exécutera en arrière-plan, n'est-ce pas? J'ai toujours le sentiment qu'un script est une exécution unique, mais ici, inotifywait continue de fonctionner, n'est-ce pas?
Ortix92
2
l'écoute sur createévénement n'est pas correcte, car vous ferez un mvsur un fichier qui peut ne pas être entièrement copié sur le disque. Voir la réponse @Gilles, en utilisant l' close_writeévénement à la place.
fduff
3
@fduff Voir la réponse de Gilles est toujours la bonne chose à faire ...
jasonwryan
17

La commande inotifywaitimprime un message chaque fois que le contenu du répertoire spécifié change. Vous devrez choisir le bon événement: pas lorsque le fichier est créé, mais lorsque Dropbox a fini de le télécharger. Je ne sais pas exactement comment fonctionne Dropbox. S'il écrit dans le fichier à sa place finale, écoutez les close_writeévénements. S'il écrit dans le fichier dans un emplacement temporaire, puis le place, écoutez les moved_toévénements. Passez les options -m -qà inotifywaitpour qu'il continue d'écouter les événements (par défaut, il n'attend que l'événement suivant) et imprime uniquement les messages pertinents.

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- arrête d'être méchant'
la source
1
Cela échoue pour les fichiers qui incluent des retours à la ligne dans leurs noms. Je n'ai pas réussi à trouver un moyen de inotifywaitproduire des noms de fichiers à terminaison nulle. Le mieux que je pouvais faire était d'utiliser un caractère moins probable que le saut de ligne, par exemple %f$'\001', et d'utiliser -d $'\001'avec while IFS= read -rou xargs.
pause jusqu'à nouvel ordre.
1
@DennisWilliamson Oui, inotifywaitc'est ennuyeux de cette façon. Vous pouvez utiliser quelque chose comme //%f, car le nom de fichier ne contiendra jamais de double barre oblique tant que le chemin à regarder ne le sera pas; alors l'ennui est du côté de l'analyse.
Gilles 'SO- arrête d'être méchant'