Se você não for usar o sistema de arquivos remoto como a fonte de dados do que foi transferido, será necessário rastrear externamente os arquivos que foram transferidos com êxito anteriormente e, em seguida, excluí-los das transferências futuras.
rsync
pode incluir e excluir arquivos baseados em padrões em um arquivo assim você pode incluir uma lista específica de arquivos em uma transferência. Em seguida, exclua essa lista das transferências futuras.
#!/usr/bin/env bash
set -e
track_dir=~/.track_xfer
inc_file="$track_dir/include_files"
exc_file="$track_dir/exclude_files"
xfer_dir=~/testrsync
xfer_dest=~/testrsync_dest
mkdir -p "$track_dir"
touch $exc_file
cd "$xfer_dir"
# find files and create rsync filter list
find . -type f -print0 | perl -e '
$/="#!/usr/bin/env bash
set -e
track_dir=~/.track_xfer
inc_file="$track_dir/include_files"
exc_file="$track_dir/exclude_files"
xfer_dir=~/testrsync
xfer_dest=~/testrsync_dest
mkdir -p "$track_dir"
touch $exc_file
cd "$xfer_dir"
# find files and create rsync filter list
find . -type f -print0 | perl -e '
$/="%pre%";
while (<>){
chomp;
$_ =~ s!^\.!!; # remove leading .
$f = quotemeta; # quote special chars
$f =~ s!\/!/!g; # fix quoted paths '/'
print $f."\n";
}' > "$inc_file"
# Run the rsync
rsync -va --delete --exclude-from "$exc_file" --include-from "$inc_file" "$xfer_dir/" "$xfer_dest"
# Add the included/transferred files to the exclusion list
cat "$inc_file" "$exc_file" > "$exc_file".tmp
sort "$exc_file".tmp | uniq > "$exc_file"
";
while (<>){
chomp;
$_ =~ s!^\.!!; # remove leading .
$f = quotemeta; # quote special chars
$f =~ s!\/!/!g; # fix quoted paths '/'
print $f."\n";
}' > "$inc_file"
# Run the rsync
rsync -va --delete --exclude-from "$exc_file" --include-from "$inc_file" "$xfer_dir/" "$xfer_dest"
# Add the included/transferred files to the exclusion list
cat "$inc_file" "$exc_file" > "$exc_file".tmp
sort "$exc_file".tmp | uniq > "$exc_file"
Você pode precisar de mais algumas citações em regex específicas em rsync
, mas a função Perl quotemeta
e suas substituições foi a primeira solução fácil que me veio à mente.
O principal problema será lidar com qualquer caractere especial em nomes de arquivos.
Se você quer lidar com novas linhas ou abas e outras coisas estranhas nos nomes, então você terá que colocar um pouco mais de trabalho no perl
(ou qualquer outro) que analise e gere a lista de padrões de inclusão. Se você puder restringir os nomes de seus arquivos de transferência a um conjunto de caracteres simples, não precisará se preocupar com essa etapa. O perl
é uma solução incompleta que deve fazer com que você ultrapasse os caracteres regex mais comuns.
O motivo para usar a lista de inclusão, em vez de permitir que rsync
puxe o próprio diretório inteiro, é para que você tenha uma lista definida / completa de arquivos para a lista de exclusões subsequente. Você provavelmente poderia obter o mesmo resultado analisando a rsync
output ou a --log-file=FILE
dos arquivos que foram transferidos, mas isso pareceu um pouco mais difícil.