script para monitorar novos arquivos em uma pasta compartilhada (host do Windows, convidado do Linux)

5

Eu preciso monitorar uma pasta compartilhada, neste caso específico o host é windows e o convidado é Ubuntu linux, para novos arquivos ou um arquivo que foi alterado. Idealmente, a solução deve funcionar independentemente da máquina host ou da máquina que coloca um arquivo no diretório compartilhado. O novo arquivo será a entrada para um processo diferente.

O conjunto de ferramentas inotifywait não detecta novos arquivos se os arquivos forem criados pelo host e colocados na pasta compartilhada.

Quais são minhas opções?

    
por Fresh Codemonger 24.08.2016 / 06:55

3 respostas

1

Você pode usar uma das ferramentas de pesquisa que pré-datam dnotify e inotify : gamin ou fam , juntamente com algo como fileschanged que é uma ferramenta inotifywait -like da CLI. Os projetos gamin e fam estão relacionados, e ambos são bem antigos (apesar de serem um pouco menos).

Para tarefas simples e portáteis, usei algo assim via cron:

if mkdir /var/lock/mylock; then
  ( cd /mnt/mypath; find . -type f -mmin +2 ) | myprocess
  rmdir /var/lock/mylock
else
  logger -p local0.notice "mylock found, skipping run"
fi

Isso usa bloqueio primitivo e um condicional GNU find para encontrar apenas arquivos antigos de dois minutos para que eu possa ter certeza de que os arquivos foram gravados completamente. No meu caso myprocess era rsync --remove-source-files --files-from=- , então os arquivos foram removidos depois de processados.

Essa abordagem também permite usar find -print0 / xargs -0 / rsync -0 para lidar com nomes de arquivos problemáticos.

Se você precisar manter todos os arquivos (antigos e novos) na mesma hierarquia de diretórios, a criação de instantâneos de listagem de diretórios e a distribuição deles também funcionarão para você:

if mkdir /var/lock/mylock; then
  ( 
    export LC_COLLATE=C  # for sort
    cd /mnt/mypath
    find . -type f -a \! -name ".dirlist.*" -printf '%p
if mkdir /var/lock/mylock; then
  ( cd /mnt/mypath; find . -type f -mmin +2 ) | myprocess
  rmdir /var/lock/mylock
else
  logger -p local0.notice "mylock found, skipping run"
fi
' | while read -d '' file; do printf "%q\n" "${file}" done > .dirlist.new [[ -f .dirlist.old ]] && { comm -13 <(sort .dirlist.old) <(sort .dirlist.new) | while read -r file; do myprocess "${file}" done } mv .dirlist.new .dirlist.new ) rmdir /var/lock/mylock else logger -p local0.notice "mylock found, skipping run" fi

Este script bash :

  1. usa find -printf para imprimir uma lista de arquivos delimitados por \ 0 (nul)
  2. usa read -d '' para processar essa lista e printf %q para escapar nomes de arquivos quando necessário
  3. compara os arquivos .dirlist novos e anteriores
  4. invoca myprocess com cada novo arquivo (citado com segurança)

(Também lidar com arquivos modificados exigiria um pouco mais de esforço, um formato de linha dupla com find ... -printf '%pwhile%s %Ts%code%' poderia ser usado, com alterações associadas aos %code% loops.)

    
por 24.08.2016 / 13:55
5

Você precisa de algo que aponte para alterações de arquivo, porque se um arquivo for modificado no lado do Windows, o kernel do Linux não saberá sobre isso. Existem alguns aplicativos existentes que podem ajudar com isso, como o Guard: link

Dependendo de suas necessidades, você pode apenas watch da listagem de arquivos (ajustando n segundos para o que for adequado):

watch --differences -n 10 ls -l </path/to/shared/dir>
    
por 24.08.2016 / 07:23
-1

Se você estiver familiarizado com o node.js e seu ecossistema, poderá usar esta biblioteca  para implementar a pesquisa em uma pasta compartilhada.

    
por 04.09.2017 / 05:04