ignora arquivos em uso (sendo gravado para) ao usar o rsync

4

Eu tenho um servidor SFTP onde os clientes estão constantemente fazendo upload de arquivos grandes. Periodicamente, quero copiar todos os arquivos completos (totalmente carregados) para outra máquina para processamento. Não quero copiar um arquivo que está sendo gravado ativamente. Existe uma maneira de conseguir isso? Atualmente estou usando o rsync, mas estou aberto a mudar para outra coisa.

    
por braindancer 06.05.2016 / 22:19

2 respostas

3

Para verificar se um arquivo está aberto no momento (se um arquivo está atualmente escrito com certeza é aberto por algum processo) a forma padrão é usar lsof :

if lsof /your/file > /dev/null; then echo "file currently open"; fi

Você pode usar este snippet para filtrar os resultados de busca somente por arquivos não abertos e usá-los para alimentar o rsync:

find . -type f -exec sh -c 'if ! lsof 'readlink -f {}' > /dev/null; then echo 'basename {}'; fi' \; | tr '\n' '
if lsof /your/file > /dev/null; then echo "file currently open"; fi
' | rsync -avz --from0 --files-from=- ./ user@host:destination/

Algumas notas:

  • readlink -f é necessário para ter o caminho completo de um arquivo, lsof aceita somente o caminho completo
  • tr '\n' '-print0' emulate encontra %code%
por 07.05.2016 / 00:52
1

Um desafio aqui é determinar se os arquivos ainda estão sendo gravados. Não há maneira perfeita de fazer isso. Acho que o melhor que você pode fazer é simplesmente verificar o último registro de data e hora modificado nos arquivos e copiar apenas os arquivos que não foram modificados por alguns minutos.

rsync por si só não pode fazer isso, mas você pode combiná-lo com o comando de localização :

cd /path/to/directory/with/files
find ./ -type f -mmin +5 -print0 | rsync --archive --verbose --from0 --files-from=- ./ yourotherserver:targetdir/

Para quebrar esse comando, ele faz duas coisas:

  1. Ele usa find ./ -type f -mmin +5 -print0 para identificar todos os arquivos que não foram modificados por pelo menos 5 minutos.
  2. Em seguida, ele alimenta essa lista em rsync usando os parâmetros --from0 e --files-from . Isso fará com que rsync considere apenas os arquivos que find identificou.
por 06.05.2016 / 22:56

Tags