Mostrando o progresso total no rsync: é possível?

197

Já pesquisei essa opção, mas encontrei somente soluções que envolvem correção personalizada . O fato de que ele não aparece em --help e nenhuma informação mais pode ser encontrada, provavelmente, indica que as respostas são 'não', mas eu gostaria de ver isso confirmado.

É possível mostrar o progresso total da transferência de arquivos com o rsync?

    
por Aron Rotteveel 05.01.2011 / 15:26

17 respostas

33

danakim está correto. Não há formas triviais de adicionar um indicador de progresso total.

A razão para isto é que quando o rsync olha para uma lista de arquivos para sincronizar, ele não sabe antecipadamente quais arquivos precisarão ser alterados. Se você está fazendo transferências delta, os próprios deltas devem ser calculados com antecedência para fornecer uma visão geral do trabalho que precisa ser feito.

Em outras palavras, a maneira mais fácil de calcular quanto trabalho deve ser feito é realmente fazer isso.

    
por 06.01.2011 / 04:10
322

Existe agora uma maneira oficial de fazer isso no rsync (versão 3.1.0 do protocolo versão 31, Testado com o Ubuntu Trusty 14.04).

#> ./rsync -a --info=progress2 /usr .
    305,002,533  80%   65.69MB/s    0:00:01  xfr#1653, ir-chk=1593/3594)

Eu tentei com a minha pasta /usr porque eu queria esse recurso para transferir sistemas de arquivos inteiros, e /usr parecia ser uma boa amostra representativa.

O --info=progress2 fornece uma boa porcentagem geral, mesmo que seja apenas um valor parcial. Na verdade, minha pasta /usr é mais de 6 shows:

#> du -sh /usr
6,6G    /usr/

e rsync demoraram muito tempo para analisar tudo. Então, quase todo o tempo que a porcentagem que eu vi foi de cerca de 90% concluída, mas mesmo assim é reconfortante ver que algo está sendo copiado:)

Referências:

por 24.10.2012 / 11:13
42

Você pode com 'pv' ( apt-get install pv com Debian e ubuntu). Eu recomendo monitorar o número de arquivos transferidos, uma vez que a quantidade de dados transferidos não está correlacionada ao tamanho dos arquivos, mas no delta entre a origem e o destino. E contar arquivos contará o mesmo progresso para um grande delta e outro com um pequeno delta. O que significa que, em qualquer caso, a estimativa de ETA pode estar muito distante. O ETA baseado em tamanho só funciona se o seu destino estiver vazio, neste caso delta == tamanho da fonte.

A idéia geral é emitir uma linha por arquivo 'transferido' do rsync e contar essas linhas com 'pv':

rsync -ai /source remote:/dest | pv -les [number of files] >/dev/null

Eu costumo fazer backup de sistemas de arquivos inteiros (por vários motivos), neste caso você pode usar o muito mais barato df para obter o número de arquivos (em vez de du ou find que percorrerá sua hierarquia de origem tempo após rsync fez isso). A opção -x aparece para garantir que o rsync permaneça no mesmo sistema de arquivos de origem (e não siga outras montagens internas):

rsync -aix /source remote:/dest | pv -les $(df -i /source | perl -ane 'print $F[2] if $F[5] =~ m:^/:') >/dev/null

Se você quiser contar os arquivos em / source de uma maneira geral, use find /source|wc -l (aviso novamente: pode ser lento e pesado em E / S).

    
por 10.06.2011 / 10:22
28

Para transferências longas, estou satisfeito com a execução de du -s em ambos os lados. Mesmo watch -n1 du -s , se eu me sentir realmente ansioso.

watch executa um comando ( du -s here) periodicamente (a cada 1 segundo aqui) e mostra a saída em tela cheia.

    
por 05.01.2011 / 16:30
21

Juntamente com - info = progress2 Você também pode desativar a recursão incremental. Isso criará toda a lista de arquivos no começo e, assim, dará uma ideia melhor da progresso geral (pelo menos em número de arquivos, eu não acho que ele verifica o tamanho do arquivo). Existe um trade-off. Isso é mais dispendioso em termos de memória e atrasa o início da transferência real. Provavelmente melhor usado em conexões de link mais lento, e certamente não é ótimo para arquivos de arquivos.

O seguinte é da página man do rsync sob os detalhes de -r --recursivo

Incremental recursion can be disabled using the --no-inc-recursive option or its shorter --no-i-r alias.

(fonte: link )

Além disso, se você especificar --delete-before, ele forçará a recursão completa no início, necessária para excluir arquivos órfãos (arquivos que existem no dest, mas não na origem).

    
por 16.10.2014 / 19:56
11

Basicamente não. Você só pode mostrar o progresso por arquivo com o sinalizador --progress, mas é sobre isso.

Eu estou supondo que você pode escrever um wrapper em torno dele ou usar qualquer um dos patches que você já encontrou, mas você deve se perguntar se realmente vale a pena, você realmente precisa de um progresso total para o rsync?

    
por 05.01.2011 / 15:50
7

Eu também procurei como mostrar o progresso total com o rsync e encontrei um respondedor útil desta postagem: link

Basicamente, você pode usar - info = progress2 na versão de desenvolvimento do rsync 3.1.0 . Veja o que o documento disse:

There is also a --info=progress2 option that outputs statistics based on the whole transfer, rather than individual files. Use this flag without outputting a filename (e.g. avoid -v or specify --info=name0 if you want to see how the transfer is doing without scrolling the screen with a lot of names. (You don't need to specify the --progress option in order to use --info=progress2.)

    
por 04.07.2013 / 14:30
7

Eu usei a resposta do zerodeux e escrevi meu próprio script:

#!/bin/bash

RSYNC="ionice -c3 rsync"
# don't use --progress
RSYNC_ARGS="-vrltD --delete --stats --human-readable"
SOURCES="/dir1 /dir2 /file3"
TARGET="storage::storage"

echo "Executing dry-run to see how many files must be transferred..."
TODO=$(${RSYNC} --dry-run ${RSYNC_ARGS} ${SOURCES} ${TARGET}|grep "^Number of files transferred"|awk '{print $5}')

${RSYNC} ${RSYNC_ARGS} ${SOURCES} ${TARGET} | pv -l -e -p -s "$TODO"
    
por 07.02.2012 / 23:44
6

Eu usei a resposta do zerodeux e escrevi meu próprio script BASH:

#!/bin/bash

RSYNC="ionice -c3 rsync"
# don't use --progress
RSYNC_ARGS="-vrltD --delete --stats --human-readable"
SOURCES="/dir1 /dir2 /file3"
TARGET="storage::storage"

#echo "Executing dry-run to see how many files must be transferred..."
TODO=$(find ${SOURCES} | wc -l)

${RSYNC} ${RSYNC_ARGS} ${SOURCES} ${TARGET} | pv -l -e -p -s "$TODO"

Mudei o teste de execução TODO para

TODO=$(find ${SOURCES} | wc -l)

Ele encontra o número de arquivos muito rápido!

    
por 03.01.2013 / 12:00
6

Se você não tem o rsync mais recente (por exemplo, o OS X possui o 2.6.9) e não pode usar o --info=progress2 , aqui está outra alternativa para salvar-se das páginas de rolagem de texto no progresso:

rsync -aPh <source> <destination> | xargs -L1 printf "[2K\rTransferring: %s"

Isso imprimirá, em uma linha, o nome do arquivo mais recente que está sendo transferido:

Transferring: the-latest.file

    
por 02.05.2016 / 09:18
4

Use

lsof -ad3-999 -c rsync

Para ver quais arquivos o rsync tem atualmente aberto (mostrará o tamanho do arquivo) rsync copia em um arquivo oculto localmente

    
por 20.03.2014 / 10:20
4

Eu faria um comentário, mas não tenho reputação suficiente. Em resposta ao comentário de naught101 à resposta escolhida, a opção --progress mostra quantos arquivos foram transferidos para fora do valor total a ser transferido. Eu não percebi isso até olhar para este post e olhar a saída com mais cuidado.

O status 'para verificar' mostra quantos arquivos são deixados fora do total. Isso é mais útil quando rsync'ing para um novo destino para que você saiba que todos os arquivos serão totalmente copiados.

Da página do manual:

When [each] file transfer  finishes,  rsync  replaces  the
progress line with a summary line that looks like this:

    1238099 100%  146.38kB/s    0:00:08  (xfer#5, to-check=169/396)

In this example, the file was  1238099  bytes  long  in
total,  the average rate of transfer for the whole file
was 146.38 kilobytes per second over the 8 seconds that
it took to complete, it was the 5th transfer of a regu-
lar file during the current rsync  session,  and  there
are 169 more files for the receiver to check (to see if
they are up-to-date or not) remaining out  of  the  396
total files in the file-list.
    
por 05.04.2013 / 22:01
3

Observe a advertência aqui que mesmo --info = progress2 não é totalmente confiável, já que essa porcentagem é baseada no número de arquivos que o rsync 'sabe' sobre quando o progresso está sendo exibido. Isso não é necessariamente o número total de arquivos que precisavam ser sincronizados (por exemplo, se descobrisse um grande número de arquivos grandes em um diretório profundamente aninhado). Uma maneira de garantir que --info = progresso2 não "retroceder" na indicação de progresso seria forçar o rsync a varrer todos os diretórios recursivamente antes de iniciar a sincronização (em vez de seu comportamento padrão de fazer uma varredura incrementalmente recursiva), também fornecendo a opção --no-inc-recursiva. Note, no entanto, que esta opção também aumentará o uso da memória rsync e o tempo de execução.

    
por 25.02.2014 / 04:44
2

Eu uso um script que extrai as informações de / proc // io para o processo de rsync (ou qualquer outro processo para esse assunto) e sabendo que o valor total a ser transferido é calculado o progresso.

#!/bin/bash

usage()
{
   echo "usage: $0 PID BASEMSIZE [DELAY[s|m|h]]"
}

if [ $# -lt 2 ]; then
   usage
   exit 1
elif [ $# -eq 3 ]; then
   DELAY=$3
else
   DELAY=5s
fi

PID=$1
PBASE='echo "scale=2; $2/1024"|bc'

R_PID=$PID
W_PID=$PID

R_SPEED_MAX=0
W_SPEED_MAX=0
R_SPEED_CUM=0
W_SPEED_CUM=0
R_SPEED_AVG=0
W_SPEED_AVG=0

ETA=0
ETA_H=0
ETA_M=0
ETA_S=0

while [ ! -r /proc/$PID/io ];
do
   clear
   echo "Waiting for process with PID=$PID to appear!"
   sleep 1
done

B_READ_PREV='cat /proc/$R_PID/io|awk '$1 ~ /^read_bytes/ {print $2}''
B_WRITE_PREV='cat /proc/$W_PID/io|awk '$1 ~ /^write_bytes/ {print $2}''
T1='date +%s.%N'

count=0
while true
do
   [ ! -r /proc/$PID/io ] && break
   clear
   B_READ='cat /proc/$R_PID/io|awk '$1 ~ /^read_bytes/ {print $2}''
   B_WRITE='cat /proc/$W_PID/io|awk '$1 ~ /^write_bytes/ {print $2}''
   BL_READ='echo "scale=2; ($B_READ-$B_READ_PREV)/1048576"|bc'
   BL_WRITE='echo "scale=2; ($B_WRITE-$B_WRITE_PREV)/1048576"|bc'
   GB_DONE='echo "scale=2; $B_WRITE/1073741824"|bc'
   PDONE='echo "scale=2; $GB_DONE*100/$PBASE"|bc'
   T2='date +%s.%N'
   TLOOP='echo "scale=2; ($T2-$T1)/1"|bc'
   R_SPEED='echo "scale=2; $BL_READ/$TLOOP"|bc'
   W_SPEED='echo "scale=2; $BL_WRITE/$TLOOP"|bc'

   if [ $count -ge 1 ]; then
      R_SPEED_CUM='echo "scale=2; $R_SPEED_CUM+$R_SPEED"|bc'
      R_SPEED_AVG='echo "scale=2; $R_SPEED_CUM/$count"|bc'
      W_SPEED_CUM='echo "scale=2; $W_SPEED_CUM+$W_SPEED"|bc'
      W_SPEED_AVG='echo "scale=2; $W_SPEED_CUM/$count"|bc'
      [ 'echo "scale=2; $W_SPEED > $W_SPEED_MAX"|bc' -eq 1 ] && W_SPEED_MAX=$W_SPEED
      [ 'echo "scale=2; $R_SPEED > $R_SPEED_MAX"|bc' -eq 1 ] && R_SPEED_MAX=$R_SPEED
   fi

   if [ 'echo "scale=2; $W_SPEED_AVG > 0"|bc' -eq 1 ]; then
      ETA='echo "scale=2; (($PBASE-$GB_DONE)*1024)/$W_SPEED_AVG"|bc'
      ETA_H='echo "scale=0; $ETA/3600"|bc'
      ETA_M='echo "scale=0; ($ETA%3600)/60"|bc'
      ETA_S='echo "scale=0; ($ETA%3600)%60"|bc'
   fi

   echo "Monitoring PID: $PID"
   echo
   echo "Read:       $BL_READ MiB in $TLOOP s"
   echo "Write:      $BL_WRITE MiB in $TLOOP s"
   echo
   echo "Read Rate:  $R_SPEED MiB/s ( Avg: $R_SPEED_AVG, Max: $R_SPEED_MAX )"
   echo "Write Rate: $W_SPEED MiB/s ( Avg: $W_SPEED_AVG, Max: $W_SPEED_MAX )"
   echo
   echo "Done: $GB_DONE GiB / $PBASE GiB ($PDONE %)"
   [ 'echo "scale=2; $ETA > 0"|bc' -eq 1 ] && printf "ETA: %02d:%02d:%05.2f (%.2fs)\n" $ETA_H $ETA_M $ETA_S $ETA
   echo "Elapsed: 'ps -p $PID -o etime='"

   T1='date +%s.%N'
   sleep $DELAY
   B_READ_PREV=$B_READ
   B_WRITE_PREV=$B_WRITE
   ((count++))
done
echo "----- Finished -------------------------------------------------------------------"
    
por 16.09.2014 / 20:17
1

Talvez você possa combinar pv com rsync. Especialmente o parâmetro --size poderia ser útil. Dando uma olhada nos documentos, algo como pv --size $(du -sb . | awk '{print $1}') | rsync -av . host:/your/path deve funcionar.

Aqui você encontrará os documentos e o software.

Não tentei isso sozinho.

    
por 06.01.2011 / 08:08
1

Pode ser um pouco tarde aqui, mas futuros candidatos a respostas podem se beneficiar.

Isso estava me incomodando também, então achei que ia ficar sujo e escrever meu primeiro roteiro. O zenity do pacote deve ser instalado (sudo apt-get install zenity), mas tenho certeza que provavelmente já estará lá. Além disso, eu uso o wmctrl (controle do gerenciador de janelas) para alterar o título do diálogo de progresso quando estiver pronto, é facilmente instalável, mas não fará diferença se você não o fizer. Eu só gosto de ver quando é feito no meu painel.

O script basicamente solicita um diretório de origem e destino, calcula a porcentagem do destino sobre o tamanho da fonte usando du e exibe uma barra de progresso.

Nota: Isso só funciona para a sincronização completa de diretório / arquivo (normalmente eu o uso para fazer backups do cache do apt), portanto nenhuma opção --exclude = / file / in / Source-directory. Também não funcionará se houver arquivos / diretórios no diretório de destino que não estejam no diretório de origem. Não tenho certeza se funciona para origens / destinos remotos, pois nunca tive a necessidade ou os recursos para testá-lo.

PS. Este script pode ser muito mal escrito ou muito ineficiente, (script-virgin here), mas pelo menos serve ao seu propósito e é claro que você é bem-vindo para editá-lo e melhorá-lo para atender às suas necessidades. PSS. Além disso, não consegui o botão cancelar para matar o rsync, então eu o removi.

    #!/bin/bash
set -e;

WELC="Running RsyncP as $USER";

function echo_progress()
{
    while (($TRANSFER_SIZE > 1000));    
    do  
        DEST_SIZE=$(du -s $DEST_FOLDER | cut -d / -f 1); 
        ((TRANSFER_SIZE=$SOURCE_SIZE-DEST_SIZE)); 
        PROGRESS_PERC=$((DEST_SIZE*100/SOURCE_SIZE));
        echo $PROGRESS_PERC;
        sleep 0.1s;
    done;
    echo 100;
    zenity --info --width=250 --title=RsyncP --text="File syncing complete!";
}

function get_input()
{
    dirs=$(zenity --forms --width=500 --title="RsyncP" --text="Enter source And destination directories" --add-entry="Source: " --add-entry="Destination: " --separator=" ");

    SOURCE_FOLDER=$(echo $dirs | cut -d' ' -f 1);
    DEST_FOLDER=$(echo $dirs | cut -d' ' -f 2);

    OPTIONS=-$(zenity --list --title="RsyncP Options" --text="Select rsync options" --separator='' --height=470 --width=470 --checklist --column "activate" --column "Option" --column "Description" FALSE v "Verbose (Terminal only)" FALSE q "Quiet, supress non-error messages (Terminal only)" FALSE P "Progress (Terminal only)" FALSE a "Archive (lrpog)" TRUE r "Recurse into directories" FALSE p "Preserve permissions" FALSE o "Preserve owner" FALSE g "Preserve group" FALSE l "Copy symlinks as symlinks");

    zenity --question --no-wrap --title="RsyncP" --width=500 --text="rsync  $OPTIONS $SOURCE_FOLDER $DEST_FOLDER\nDo you want to continue?";

    SOURCE_SIZE=$(du -s $SOURCE_FOLDER | cut -d / -f 1); 
    DEST_SIZE=$(du -s $DEST_FOLDER | cut -d / -f 1); 
    PROGRESS_PERC=$((DEST_SIZE*100/SOURCE_SIZE)); 
    TRANSFER_SIZE=1001;
}

if [ "$(id -u)" != "0" ]; then
    zenity --question --title=RsyncP --text="$WELC, Continue?";
    get_input;
    rsync  $OPTIONS $SOURCE_FOLDER $DEST_FOLDER & 
    echo_progress | zenity --progress --title=RsyncP --no-cancel --auto-close --text="Copying from \n$SOURCE_FOLDER to \n$DEST_FOLDER" ;

else            
    zenity --question --title=RsyncP --text="$WELC, Continue?";
    get_input; 
    sudo rsync  $OPTIONS $SOURCE_FOLDER $DEST_FOLDER & 
    echo_progress | zenity --progress --title=RsyncP --no-cancel --auto-close --text="Copying from \n$SOURCE_FOLDER to \n$DEST_FOLDER" ;
fi
    
por 08.01.2014 / 00:10
1

Se a sua versão de rsync não aceitar a opção --info=progress2 , você poderá usar tqdm :

Para instalar:

pip install tqdm

Para usar:

$ rsync -av /source /dest | tqdm --unit_scale | wc -l
10.0Mit [00:02, 3.58Mit/s]
    
por 26.07.2017 / 20:12