Usando o inotify para monitorar um diretório, mas não funcionando 100%

10

Eu escrevi um script bash para monitorar um diretório específico /root/secondfolder/:

#!/bin/sh

while inotifywait -mr -e close_write "/root/secondfolder/"
do
    echo "close_write"
done

Quando eu criar um arquivo chamado fourth.txtno /root/secondfolder/e material de escrita para ele, salve e feche-lo, ele exibe o seguinte:

/root/secondfolder/ CLOSE_WRITE,CLOSE fourth.txt

No entanto, ele não ecoa "close_write". Por que é que?

mib1413456
fonte

Respostas:

16

inotifywait -m é o modo "monitor" : ele nunca sai. O shell o executa e aguarda o código de saída para saber se deve executar o corpo do loop, mas isso nunca ocorre.

Se você remover -m, ele funcionará:

while inotifywait -r -e close_write "/root/secondfolder/"
do
    echo "close_write"
done

produz

Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
/root/secondfolder/ CLOSE_WRITE,CLOSE bar
close_write
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
...

Por padrão, o inotifywait "sai após o primeiro evento", que é o que você deseja em uma condição de loop.


Em vez disso, você pode preferir ler a saída padrão de inotifywait:

#!/bin/bash

while read line
do
    echo "close_write: $line"
done < <(inotifywait -mr -e close_write "/tmp/test/")

Esse script (bash) lerá cada linha de saída do inotifywaitcomando na $linevariável dentro do loop, usando a substituição do processo . Evita a instalação de relógios recursivos sempre que o loop for caro, o que pode ser caro. Se você não pode usar bash, você pode canalizar o comando para o loop em vez disso: inotifywait ... | while read line .... inotifywaitproduz uma linha de saída para cada evento nesse modo; portanto, o loop é executado uma vez para cada um.

Michael Homer
fonte
2
Canalizar o comando para o loop funciona, obrigado!
Mib1413456