Come utilizzare inotifywait per guardare una directory per la creazione di file di un'estensione specifica


21

Ho visto questa risposta .

Dovresti considerare l'utilizzo di inotifywait, come esempio:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done

La mia domanda è che lo script sopra controlla una directory per la creazione di file di qualsiasi tipo, ma come posso modificare il inotifywaitcomando per segnalare solo quando viene creato (o spostato nella directory) un file di un determinato tipo / estensione - ad esempio, dovrebbe segnala quando .xmlviene creato un file.

COSA HO PROVATO:

Ho eseguito il inotifywait --helpcomando e ho letto le opzioni della riga di comando. Ha --exclude <pattern>e --excludei <pattern>comanda di ESCLUDERE i file di determinati tipi (usando regEx), ma ho bisogno di un modo per INCLUDERE solo i file di un certo tipo / estensione.


A proposito, usare pathsopra non è probabilmente il miglior nome di variabile se vuoi giocare con questo prima in una shell. Se lo usi, non sarai in grado di usare i comandi e tutto, poiché questo ha praticamente ignorato lo standard PATH. Quindi consiglio di usare un nome var alternativo, come fpathinvece. cioè while read fpath action fileallora qualsiasi comando standard normalmente disponibile dalla tua shell sarà ancora.
Baptiste Mathus,

è ridicolo che non ci sia un'opzione include.
erandros,

Risposte:


17

come posso modificare il comando inotifywait per segnalare solo quando viene creato un file di un determinato tipo / estensione

Si prega di notare che questo è un codice non testato poiché non ho accesso al inotifymomento. Ma qualcosa di simile a questo dovrebbe funzionare:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        if [[ "$file" =~ .*xml$ ]]; then # Does the file end with .xml?
            echo "xml file" # If so, do your thing here!
        fi
    done

2
Questo funziona e l'ho provato con inotifywait.
TheBetterJORT

1
Come si esegue questo? È un comando una tantum o deve essere eseguito in un ciclo o qualcosa del genere? Forse come parte di incron(spero di no).
SDsolar,

@SDsolar Varia. Per me, di solito corro inotifycon nohupo lo avvio con un servizio systemd personalizzato. Molto spesso quest'ultimo.
Maulinglawns,

9

Usa un doppio negativo:

inotifywait -m --exclude "[^j][^s]$" /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
    done

Ciò includerà solo file javascript


1
Bene, mi piace che sposta il filtro inotifywaitpiuttosto che farlo generare un enorme output per tutti i file e filtrare in seguito (come nell'altra risposta). Non ci ho provato, ma immagino che sarebbe un po 'più veloce.
TMG

Questo è proprio quello che stavo cercando. Come modificare l' --excludeinput per controllare i .extfile. Questo viene eseguito solo una volta o in un ciclo for?
Kurokirasama,

È un demone, quindi funzionerà fino a quando non si blocca o non lo spegni :)
Jonas Earendel,

Scusa, ho perso la prima domanda. inotifywait -m --exclude "[^.][^e][^x][^t]$" /home/jonas/Skrivbord/test -e create -e moved_to | while read path action file; do echo "The file '$file' appeared in directory '$path' via '$action'" done Sono sicuro che il regex può essere ottimizzato, ma questo bambino funziona :)
Jonas Earendel,

Thanxs !! Lo proverò !!
Kurokirasama,

3

Sebbene l'approccio doppio negativo della risposta precedente sia una buona idea poiché (come osservato da TMG) ​​in effetti sposta il lavoro di filtraggio inotifywait, non è corretto.

Ad esempio, se un file termina, asallora non corrisponderà [^j][^s]$perché la lettera finale snon corrisponde [^s], quindi non verrà esclusa.

In termini booleani, se Sè la dichiarazione:

"la lettera finale è s"

ed Jè la dichiarazione:

"la penultima lettera è j"

allora il valore del --excludeparametro dovrebbe essere semanticamente uguale a not(J and S), che secondo le leggi di De Morgan è not(J) or not(S).

Un altro potenziale problema è che in zsh, $pathè una variabile incorporata che rappresenta l'equivalente di array di $PATH, quindi la while read path ...linea sarà completamente incasinata $PATHe farà diventare tutto non eseguibile dalla shell.

Pertanto l'approccio corretto è:

inotifywait -m --exclude "[^j].$|[^s]$" /path -e create -e moved_to |
    while read dir action file; do
        echo "The file '$file' appeared in directory '$dir' via '$action'"
    done

Notare ciò .che è necessario dopo [^j]per assicurarsi che la corrispondenza sia applicata nella penultima posizione, e anche che il |personaggio (che rappresenta il booleano O menzionato sopra) non dovrebbe essere evitato qui perché --excludeaccetta espressioni regolari estese POSIX.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.