Bash script para monitorear el cambio de archivo y ejecutar el comando

12

Tengo una carpeta con un montón de subcarpetas, estas carpetas se han asciidoctorformateado con .adocextensión.

Cada vez que realizo cambios en los archivos (lo cual es frecuente) necesito ejecutar

asciidoctor -q filename.adoc

para compilarlo en formato HTML.

Estoy tratando de automatizar el proceso. hasta ahora he venido con esto usando entr :

ls *.adoc | entr asciidoctor -q *.adoc

pero solo funciona con carpetas existentes, no para subcarpetas. He intentado esta variación, pero no funciona:

find . -name '*.adoc' | entr asciidoctor -q *.adoc

¿Alguna idea de cómo podría implementar este proceso de automatización para todas las subcarpetas?

salvado
fuente
1
Posible duplicado de ¿Cómo se detectan cambios en el archivo
Anwar

Respuestas:

17

Linux proporciona una interfaz agradable para monitorear todos los eventos del sistema de archivos, como crear, modificar y eliminar archivos. La interfaz es una inotifyfamilia de llamadas al sistema, las utilidades del espacio de usuario que aprovechan estas llamadas son proporcionadas por el inotify-toolspaquete en Ubuntu (disponible en el repositorio del universo). Si aún no lo tiene, instálelo mediante:

sudo apt-get install inotify-tools

inotify-toolsproporciona inotifywaity inotifywatchbinarios, necesitamos el primero.


Por lo tanto, desea ejecutar el comando asciidoctor -q some_filecuando .adocse modifique cualquier archivo ( some_fileserá reemplazado por eso), si es así, suponiendo que sus .adocarchivos estén en el directorio /foo/bar, puede configurar el reloj:

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc
  • -qhabilita el modo silencioso, sin información de inotifywaitsí mismo

  • -m habilita el modo monitor, de lo contrario, saldrá después del primer evento

  • --event modify, solo nos interesa el modifyevento, es decir, cuando se modifica un archivo. Otros valores posibles incluyen open, closeetc.

  • --format %w, solo queremos el nombre del archivo que se modifica en lugar de un montón de otra información, ya que usaremos el nombre del archivo como entrada para otro comando

  • /foo/bar/*.adocse expandirá a todos los .adocarchivos en el /foo/bardirectorio


Ahora lo anterior le mostrará el nombre del archivo cada vez que se modifique alguno, ahora para ejecutar el comando en el nombre del archivo (suponiendo que el comando tome argumentos a través de STDIN):

inotifywait -qm --event modify --format '%w' /foo/bar/*.adoc | asciidoctor -q

También puede configurar un reloj recursivo en el directorio, luego deberá usarlo greppara filtrar solo los archivos deseados. Aquí configura el reloj recursivamente ( -r) en el directorio /foo/bary lo usa greppara filtrar solo .adocarchivos:

inotifywait -qrm --event modify --format '%w%f' /foo/bar | grep '\.adoc$' | asciidoctor -q

Al mirar directorios, el especificador de formato de salida se %wresuelve en el nombre del directorio, por lo que debemos %fobtener el nombre del archivo. Mientras mira los archivos, %fresolvería vaciar la cadena.

Tenga en cuenta que, también puede ejecutar inotifywaiten modo daemon ( -d), también puede hacer un script de todo, y / o ejecutar en segundo plano, y / o jugar con él más otras opciones.

Además, puede reemplazarlo asciidoctorcon cualquier otro comando de su elección, si lo desea.

Comprueba man inotifywaitpara tener más idea.

heemayl
fuente
Gracias funcionó. También tengo algo similar para OSX. pero supongo que este no es el lugar correcto para preguntar.
salvado
@bran Sí, en mi humilde opinión vaya a UL , puede usar esto como referencia.
heemayl
Gran respuesta, solo una pequeña corrección. -q hace que el programa sea "menos detallado", -qq (doble q) lo hace completamente silencioso excepto por errores fatales.
jotadepicas
4

El uso inotifywaites el enfoque típico, pero también hay una utilidad separada llamada inotify-hookableque simplemente te permite ejecutar un comando cuando cambia un archivo (o directorio):

inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'

Parece salir después de activar el comando una vez; No veo una opción para la observación continua, por lo que podría hacer algo como:

while true; do
    inotify-hookable -f filename.adoc -c 'asciidoctor -q filename.adoc'
    echo "== $(date) : executed, continuing to monitor..."
done

Tenga en cuenta que hay opciones para monitorear varios archivos o un directorio, de forma recursiva, y opciones para ignorar archivos / rutas.

Miguel
fuente
inotify-hookable no sale después de ejecutar el comando para mí. Hmm
Max
inotify-hookable se instala desde un paquete diferente:sudo apt-get install inotify-hookable
Bruno Silvano
3

Existen muchas herramientas, especialmente si busca en su repositorio

apt-cache search monitor | grep file

lo que nos da muchas herramientas. Pero no tienes que probarlos porque hice eso.

He probado estas herramientas y muchas otras:

  • inotificar
  • fswatch
  • filewatch
  • muestra de tela
  • archivos cambiados
  • entr

Entre estas herramientas encontré tres de ellas útiles y confiables:

  • direvent | GNU escrito en C
  • iwatch | en Perl
  • fsniper

Y entre estos tres, el direvent es el mejor sin duda.

Es tan útil y confiable de usar que lo he usado para una tubería simple con mis microservicios que tengo.

direvent.conf archivo para ver

syslog {
    facility local0;
    tag "direvent";
    print-priority yes;
}

watcher {
    path /var/www/html/ir/jsfun/build/react recursive;
    file "*.js";
    event write;
    command "/usr/bin/xdotool search --onlyvisible  --class firefox key F5";
    option (stdout, stderr, wait);
}

Este es solo uno de los archivos de configuración que tengo en el que cada vez que hay un cambio para escribir , se ejecuta este comando, que también podría ser un script .

No es necesario usar whileloop u otras cosas.


caracteristicas

  • viendo recursivamente un directorio
  • se puede ejecutar en primer plano o en segundo plano como un demonio
  • portátil. Lo tengo en Ubuntu, así como en el servidor CentOS7
  • informe de nombre de archivo
  • regex para admitir coincidencia de archivos
  • visualización de archivos múltiples (ver más de un solo tipo de archivo)
  • sincronizar la ejecución de comandos (si tenemos observadores múltiples)
  • manejo de syslog (log to syslog si queremos)
  • Diseño fácil y bueno de CLI y archivo de configuración para trabajar

Desarrollado por Sergey Poznyakoff .


Instalando

sudo apt install direvent

Pero instalarlo usando su código fuente es bastante fácil y directo, lo que le brinda la última versión (en este momento es: 5.1).

Shakiba Moshiri
fuente
-3

Bueno, te recomiendo lo siguiente.

#!/bin/bash
#Script
for SRC in *.adoc; 
      do
      asciidoctor -q $SRC
  done
SAGAR Nair
fuente
1
OP quiere ejecutar el comando solo cuando se realizan modificaciones ..
heemayl