Como implementar um esquema de rotação com o rsync

3

Eu tenho um diretório remoto cada vez maior de arquivos que gostaria de classificar e filtrar antes que eu rsync deles, com o objetivo de manter sempre apenas os arquivos N mais recentes no diretório de destino (ou seja, um esquema de rotação, mais ou menos). Como rsync não parece ter opções para isso, eu tenho usado a técnica de "inserir um comando remoto arbitrário", descrito aqui:

link

com o qual eu criei este comando, que executo como cron no host de destino:

rsync -vrzO --delete \
    -e ssh <remote_host>:'$(cd <remote_dir> && ls -t $PWD/* | head -n 25)' \
    <destination_dir>

Isso funciona bem na primeira vez (ou seja, quando o diretório dest está vazio): somente os 25 arquivos mais recentes são copiados. Mas quando a janela "desliza para frente" (ou seja, quando a chegada de um arquivo mais novo deve empurrar um arquivo mais antigo para fora, localmente), o problema é que a opção --delete não funciona como eu esperava. Meu palpite é que, uma vez que os arquivos remotos filtrados ainda existem (ou seja, eles estão sendo temporariamente ocultados pelo comando '$(..)' inserido), então rsync simplesmente não pode filtrá-los localmente. Meu entendimento é correto, e existe uma maneira melhor?

    
por cjauvin 25.11.2011 / 18:18

2 respostas

3

Você pode simular seu comando como

rsync -vrzO --delete -e ssh <remote_host>:'<remote_dir>/file1 <remote_dir>/file2' <destination_dir>/ , ou seja, substituindo a saída de cd <remote_dir> && ls -t $PWD/* | head -n 2 .

O --delete de rsync funciona em diretórios e sua substituição de comandos está fornecendo uma lista de arquivos. Portanto, --delete não está funcionando.

Trecho de man rsync :

--delete

This tells rsync to delete extraneous files from the receiving side (ones that aren’t on the sending side), but only for the directories that are being synchronized. You must have asked rsync to send the whole directory (e.g. "dir" or "dir/") without using a wildcard for the directory’s contents (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus gets a request to transfer individual files, not the files’ parent directory.

    
por 25.11.2011 / 20:44
0

Monte o diretório remoto em sshfs . Então você pode tratá-lo como um diretório local.

Agora, para classificar arquivos por hora de modificação, a maneira mais fácil é zsh 's qualificadores glob . Os 25 arquivos mais recentes em um diretório são

*(NDom[1,25])

Então, se você deseja copiar primeiro, exclua os arquivos estranhos no destino:

for x in source/*(NDom[1,25]); do
  y=destination/${x:t}
  if [[ ! -e $y || $x -nt $y ]]; then cp -p $x $y; fi
done
destination_files=(destination/*(NDom[1,25]))
if [[ ${#destination_files} -gt 25 ]]; then
  shift $((${#destination_files} - 25)) destination_files
  rm $destination_files
fi

Aqui está outro método que exclui os arquivos antes de copiar. Este exclui o arquivo mais antigo quando está prestes a copiar um novo arquivo e já existe um complemento completo no destino.

destination_files=(destination/*(ND)); destination_count=$#destination_files
for x in source/*(NDom[1,25]); do
  y=destination/${x:t}
  if [[ $destination_count -gt 25 && ! -e $y ]]; then rm destination/*(NDom[-1]); fi
  if [[ ! -e $y || $x -nt $y ]]; then cp -p $x $y; fi
done

(Atenção: o código acima foi digitado diretamente no navegador, eu não testei).

    
por 28.11.2011 / 01:58

Tags