Como executar um comando quando o conteúdo de um diretório é atualizado?

27

Há um diretório Acujo conteúdo é alterado frequentemente por outras pessoas.

Criei um diretório pessoal Bonde mantenho todos os arquivos que já estiveram A.

Atualmente, apenas ocasionalmente corro rsyncpara obter o backup dos arquivos de Apara B. No entanto, temo a possibilidade de alguns arquivos serem adicionados Ae removidos Aantes que eu tenha a chance de copiá-los para B.

Qual é a melhor maneira de impedir que isso ocorra? Idealmente, eu gostaria que meu script de backup atual fosse executado toda vez que o conteúdo Afosse alterado.

oadams
fonte

Respostas:

29

Se você tiver o inotify-tools instalado, poderá usar inotifywaitpara disparar uma ação se um arquivo ou diretório for gravado em:

#!/bin/sh
dir1=/path/to/A/
while inotifywait -qqre modify "$dir1"; do
    /run/backup/to/B 
done

Onde o -qqcomutador é completamente silencioso, -ré recursivo (se necessário) e -eé o evento a ser monitorado, neste caso modify. De man inotifywait:

modificar
Um arquivo monitorado ou um arquivo em um diretório monitorado foi gravado.
jasonwryan
fonte
5
incrondtambém pode ser interessante.
Shawn J. Goff
11
Legal. Eu colocaria o script acima no meu bashrc para que ele seja executado quando eu fizer o login? Existe outra maneira de executá-lo o tempo todo?
Oadams 7/11
Para login, sim /etc/profilepara todo o sistema ou .bash_profileapenas para seu usuário. Para executá-lo após a inicialização, depende do seu sabor de Unix / Linux; /etc/rc.local, /etc/rc.d/ou/etc/init.d/
jasonwryan 7/11
11
Para diretórios maiores que você pode querer considerar o uso do --monitorswitch (e canalizar a saída para o loop em vez), caso contrário, há um monte de sobrecarga quando inotifywaité iniciada uma e outra vez
Tobias KIENZLER
Com que confiabilidade essa solução funcionaria para executar um script para cada arquivo adicionado em uma árvore de diretórios por meio de um servidor FTP (digamos que um novo arquivo seja adicionado a cada 3 minutos, em média, e isso pode durar anos)? Se não for muito, existe uma solução alternativa?
Nikola Novak
5

A rigor, se alguém soltar um arquivo e removê-lo muito rapidamente, você poderá perdê-lo. O uso do inotify (no Linux ou um recurso semelhante em outros departamentos) reduz a janela de risco.

Se você pode montar o sistema de arquivos de sua escolha nesse diretório (eu sei que isso pode não ser uma opção), você pode colocar um que registre todas as versões de arquivo, por exemplo, copyfs .

Gilles 'SO- parar de ser mau'
fonte
4

Experimente entra ferramenta de linha de comando que pode executar comandos arbitrários quando os arquivos são alterados. Desde a versão 2.9, uma opção de observação de diretório ( -d) foi adicionada para reagir a eventos quando um novo arquivo é adicionado a um diretório.

Exemplo para executar o utilitário se um novo arquivo for adicionado ao projeto:

$ while true; do
> echo src/* | entr -d your_command
> done

No modo de observação de diretório, o diretório pai de cada arquivo é incluído implicitamente na lista de observação.

A única implicação disso é que, se um novo arquivo aparecer, ele deverá sair para permitir que um loop de shell externo verifique novamente o sistema de arquivos.

Aqui está a versão sem uma opção de observação de diretório:

$ while true; do
> echo src/* src | entr your_command
> done

Aqui está um exemplo mais simples, dependendo de suas necessidades:

$ ls -d * | entr sh -c 'rsync -vuar A B'

Consulte o site entrproject.org para obter mais detalhes.

kenorb
fonte
3

O programa que você está procurando é inotify.

Kevin
fonte