GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo ejecutar un comando cada vez que cambia un archivo?

Simple, usando inotifywait (instale el inotify-tools de su distribución paquete):

while inotifywait -e close_write myfile.py; do ./myfile.py; done

o

inotifywait -q -m -e close_write myfile.py |
while read -r filename event; do
  ./myfile.py         # or "./$filename"
done

El primer fragmento es más simple, pero tiene una desventaja significativa:no hará cambios realizados mientras inotifywait no se está ejecutando (en particular, mientras myfile Esta corriendo). El segundo fragmento no tiene este defecto. Sin embargo, tenga en cuenta que asume que el nombre del archivo no contiene espacios en blanco. Si eso es un problema, use el --format opción para cambiar la salida para que no incluya el nombre del archivo:

inotifywait -q -m -e close_write --format %e myfile.py |
while read events; do
  ./myfile.py
done

De cualquier manera, hay una limitación:si algún programa reemplaza myfile.py con un archivo diferente, en lugar de escribir en el myfile existente , inotifywait morirá. Muchos editores funcionan de esa manera.

Para superar esta limitación, use inotifywait en el directorio:

inotifywait -e close_write,moved_to,create -m . |
while read -r directory events filename; do
  if [ "$filename" = "myfile.py" ]; then
    ./myfile.py
  fi
done

Alternativamente, use otra herramienta que use la misma funcionalidad subyacente, como incron (le permite registrar eventos cuando se modifica un archivo) o fswatch (una herramienta que también funciona en muchas otras variantes de Unix, usando el análogo de inotify de Linux de cada variante).


entrar (http://entrproject.org/) proporciona una interfaz más amigable para inotificar (y también es compatible con *BSD y Mac OS X).

Hace que sea muy fácil especificar múltiples archivos para ver (limitado solo por ulimit -n ), elimina la molestia de lidiar con los archivos que se reemplazan y requiere menos sintaxis bash:

$ find . -name '*.py' | entr ./myfile.py

Lo he estado usando en todo el árbol de fuentes de mi proyecto para ejecutar las pruebas unitarias para el código que estoy modificando actualmente, y ya ha sido un gran impulso para mi flujo de trabajo.

Marcas como -c (borrar la pantalla entre ejecuciones) y -d (salir cuando se agrega un nuevo archivo a un directorio monitoreado) agregue aún más flexibilidad, por ejemplo, puede hacer:

$ while sleep 1 ; do find . -name '*.py' | entr -d ./myfile.py ; done

A principios de 2018 todavía está en desarrollo activo y se puede encontrar en Debian y Ubuntu (apt install entr ); la construcción del repositorio del autor fue indolora en cualquier caso.


Escribí un programa de Python para hacer exactamente esto llamado when-changed.

El uso es simple:

when-changed FILE COMMAND...

O para ver varios archivos:

when-changed FILE [FILE ...] -c COMMAND

FILE puede ser un directorio. Ver recursivamente con -r . Utilice %f para pasar el nombre del archivo al comando.


Linux
  1. Cómo guardar la salida del comando en un archivo en Linux

  2. ¿Ejecutar un comando donde se encuentra un archivo?

  3. Cómo generar una suma de comprobación parcial de un archivo

  4. Cómo editar un archivo de texto en mi terminal

  5. ¿Cómo ejecutar un archivo PL en Linux?

Cómo usar un comando de archivo en Linux

Cómo abrir un archivo en Linux

Cómo mezclar líneas en un archivo en Linux

¿Cómo ejecutar un comando en un script de Shell?

Cómo usar el comando lsof en Linux

Cómo usar el comando shred de Linux