2010-06-04 8 views
17

Desidero avviare automaticamente una compilazione ogni volta che un file cambia.script linux che monitora le modifiche ai file all'interno delle cartelle (come autospec!)

Ho usato autospec (RSpec) in Ruby e l'ho adorato.

Come si può fare in bash?

+0

vedere http://stackoverflow.com/q/4060212/119790 –

+0

vedere anche http://stackoverflow.com/q/880263/119790 –

+0

Vedere anche http://superuser.com/questions/18151 7/how-to-execute-a-command-when-a-file-changes –

risposta

5

Dopo aver letto le risposte ai messaggi di altri, ho trovato un post (ormai andato), ho creato questo script: -

#!/bin/bash 

sha=0 
previous_sha=0 

update_sha() 
{ 
    sha=`ls -lR . | sha1sum` 
} 

build() { 
    ## Build/make commands here 
    echo 
    echo "--> Monitor: Monitoring filesystem... (Press enter to force a build/update)" 
} 

changed() { 
    echo "--> Monitor: Files changed, Building..." 
    build 
    previous_sha=$sha 
} 

compare() { 
    update_sha 
    if [[ $sha != $previous_sha ]] ; then changed; fi 
} 

run() { 
    while true; do 

     compare 

     read -s -t 1 && (
      echo "--> Monitor: Forced Update..." 
      build 
     ) 

    done 
} 

echo "--> Monitor: Init..." 
echo "--> Monitor: Monitoring filesystem... (Press enter to force a build/update)" 
run 
+9

questa è la soluzione più orribile. radunerà tutti i file da una directory ogni secondo, il che è un enorme successo in termini di prestazioni. per favore guarda la soluzione di dennis williamson !!! – kritzikratzi

+2

Si prega di rimuovere i vostri downvotes dalle mie risposte, sono risposte valide e funzionano, solo perché non sono accettabili per il vostro uso, sono stati bene per il mio, e forse anche altre persone. Quindi downvoting significa che gli altri non proveranno questa risposta. I downvotes sono in realtà solo per cose che non funzionano affatto o sono fuori tema ecc. Inoltre, per favore, modifica i tuoi commenti rimuovendo la parola orribile, è una tua opzione personale, sei libero di dire che non ha successo, ma lascialo a quel. Saluti. –

+4

Perché qualcosa funziona, non significa che sia una buona idea farlo. Secondo me la tua risposta è ugualmente banale e problematica. Non vedo alcun motivo per rimuovere il mio downvote. – kritzikratzi

5

parole chiave sono inotifywait & inotifywatch comandi

14

Date un'occhiata a incron e inotify-tools.

+0

In particolare, consultare https://github.com/tartley/rerun2 che utilizza inotify-tools e semplifica l'esecuzione di un comando personalizzato, come spiegato nella risposta trascurata di Jonathan Hartley sul superutente] (http://superuser.com/a/970780/60931) – nealmcb

5

Che ne dite di questo script? Utilizza il comando 'stat' per ottenere il tempo di accesso di un file ed esegue un comando ogni volta che si verifica un cambiamento nel tempo di accesso (ogni volta che si accede al file).

#!/bin/bash 
while true 
do 
    ATIME=`stat -c %Z /path/to/the/file.txt` 
    if [[ "$ATIME" != "$LTIME" ]] 
    then 
     echo "RUN COMMNAD" 
     LTIME=$ATIME 
    fi 
    sleep 5 
done 
+0

Grazie, un punto tho, che controlla solo un file 'ATIME'. –

+2

Bene, possiamo usare il comando ** stat ** per accedere/monitorare il tempo di accesso DIR anche: ** stat -c% Z/var/tmp ** trigger di script ogni volta che c'è qualche aggiunta o cancellazione nel DIR – VDR

+0

Io davvero come la semplicità di questa soluzione. – Richard

2

Vedi this esempio come un miglioramento su su risposta di Ian Vaughan:

#!/usr/bin/env bash 
# script: watch 
# author: Mike Smullin <[email protected]> 
# license: GPLv3 
# description: 
# watches the given path for changes 
# and executes a given command when changes occur 
# usage: 
# watch <path> <cmd...> 
# 

path=$1 
shift 
cmd=$* 
sha=0 
update_sha() { 
    sha=`ls -lR --time-style=full-iso $path | sha1sum` 
} 
update_sha 
previous_sha=$sha 
build() { 
    echo -en " building...\n\n" 
    $cmd 
    echo -en "\n--> resumed watching." 
} 
compare() { 
    update_sha 
    if [[ $sha != $previous_sha ]] ; then 
    echo -n "change detected," 
    build 
    previous_sha=$sha 
    else 
    echo -n . 
    fi 
} 
trap build SIGINT 
trap exit SIGQUIT 

echo -e "--> Press Ctrl+C to force build, Ctrl+\\ to exit." 
echo -en "--> watching \"$path\"." 
while true; do 
    compare 
    sleep 1 
done 
2

Se hai entr installato, allora in guscio si può utilizzare la seguente sintassi:

while true; do find src/ | entr -d make build; done