Para responder a questão principal em resumo, rsync
parece escrever o dobro do número de bytes, porque gera dois processos / threads para fazer a cópia, e há um fluxo de dados entre os processos e outro do processo de recebimento para o arquivo de destino.
Podemos dizer isso observando a strace
output em mais detalhes, os IDs do processo no início do arquivo e também os números do descritor de arquivo nas chamadas write
podem ser usados para informar fluxos de gravação diferentes "um do outro.
Presumivelmente, isso é para que uma transferência local funcione como uma transferência remota, somente a origem e o destino estão no mesmo sistema.
Usar algo como strace -e trace=process,socketpair,open,read,write
mostraria alguns tópicos gerados, o par de soquetes sendo criado entre eles e diferentes segmentos abrindo os arquivos de entrada e saída.
Um teste semelhante ao seu:
$ rm test2
$ strace -f -e trace=process,socketpair,open,close,dup,dup2,read,write -o rsync.log rsync -avcz --progress test1 test2
$ ls -l test1 test2
-rw-r--r-- 1 itvirta itvirta 81920004 Jun 21 20:20 test1
-rw-r--r-- 1 itvirta itvirta 81920004 Jun 21 20:20 test2
Vamos considerar uma contagem de bytes escritos para cada thread separadamente:
$ for x in 15007 15008 15009 ; do echo -en "$x: " ; grep -E "$x (<... )?write" rsync.log | awk 'BEGIN {FS=" = "} {sum += $2} END {print sum}' ; done
15007: 81967265
15008: 49
15009: 81920056
Que combina bastante com a teoria acima. Eu não verifiquei o que os outros 40kB escritos pelo primeiro thread é, mas eu assumirei que ele imprime a saída do progresso, e quaisquer metadados sobre o arquivo sincronizado que o rsync precisa transferir para o outro lado.
Eu não verifiquei, mas sugiro que, mesmo com a compactação delta ativada, talvez o final "remoto" do rsync ainda grave (a maior parte) o arquivo inteiro, resultando na mesma quantidade de gravações que com cp. A transferência entre os encadeamentos rsync é menor, mas a saída final ainda é a mesma.