Use inotifywait para mover el archivo cuando se carga en la carpeta de Dropbox

12

Estoy tratando de encontrar una manera de mover inmediatamente un archivo a otra carpeta tan pronto como aparezca en mi Dropbox en CentOS.

He buscado en Internet algunas pistas, pero no puedo ir más allá del hecho de que necesito usar inotifypara invocar un script que procesará el archivo tal como aparece.

Mi conocimiento de BASH es muy limitado y dudo que pueda escribir esto en PHP.

En otras palabras, ¿cómo puedo mover un archivo a otra carpeta tan pronto como aparece usando inotify?

Ortix92
fuente
¿Es el nombre del archivo constantemente predecible? O es la ubicación? Más detalles serían útiles ...
jasonwryan
@jasonwryan Es una carpeta de Dropbox, por lo que la ubicación es coherente. Y se aplica a cualquier archivo caído en esa carpeta.
Ortix92

Respuestas:

13

Este es un enfoque 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

Con más detalles sobre los tipos de archivos que desea mover, puede agregar algunas comprobaciones, registros, etc.

jasonwryan
fuente
No he podido probar ninguna de las respuestas sugeridas. Las cosas surgieron. Lo haremos lo antes posible! Sin embargo, tengo una pregunta. Si tuviera que poner esto en un archivo bash y ejecutarlo, supongo que se ejecutará en segundo plano, ¿correcto? Siempre tengo la sensación de que un script es una cosa que se ejecuta una vez, pero aquí inotifywait sigue ejecutándose, ¿correcto?
Ortix92
2
escuchar el createevento no es correcto, ya que lo hará mven un archivo que puede no copiarse completamente en el disco. Vea la respuesta de @Gilles, usando el close_writeevento en su lugar.
fduff
3
@fduff Ver la respuesta de Gilles siempre es lo correcto ...
jasonwryan
17

El comando inotifywaitimprime un mensaje cada vez que cambia el contenido del directorio especificado. Tendrá que elegir el evento correcto: no cuando se crea el archivo, sino cuando Dropbox ha terminado de descargarlo. No sé exactamente cómo funciona Dropbox. Si escribe en el archivo en su lugar final, escuche los close_writeeventos. Si escribe en el archivo en una ubicación temporal y luego lo mueve a su lugar, escuche los moved_toeventos. Pase las opciones -m -qa inotifywaitpara que siga escuchando eventos (de forma predeterminada, solo espera el próximo evento) e imprime solo mensajes relevantes.

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- deja de ser malvado'
fuente
1
Esto falla para los archivos que incluyen nuevas líneas en sus nombres. No pude encontrar una manera de inotifywaitgenerar nombres de archivo terminados en nulo. Lo mejor que pude hacer fue usar un personaje que sea menos probable que Newline, por ejemplo %f$'\001', y usar -d $'\001'con while IFS= read -ro xargs.
Pausado hasta nuevo aviso.
1
@DennisWilliamson Sí, inotifywaites molesto de esa manera. Puede usar algo como //%f, ya que el nombre del archivo nunca contendrá una barra doble siempre que la ruta a mirar no lo haga; entonces la molestia está en el lado del análisis.
Gilles 'SO- deja de ser malvado'