web-dev-qa-db-fra.com

Afficher la progression totale dans rsync: est-ce possible?

J'ai déjà recherché cette option, mais je n'ai trouvé que des solutions impliquant correctifs personnalisés . Le fait qu'il n'apparaisse pas dans --help et qu'aucune autre information ne puisse être trouvée indique probablement que les réponses sont "non", mais j'aimerais que cela soit confirmé.

Est-il possible d'afficher la progression totale du transfert de fichiers avec rsync?

260
Aron Rotteveel

Il existe désormais un moyen officiel de le faire dans rsync (version 3.1.0 du protocole version 31, testé avec 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)

J'ai essayé avec mon /usr dossier parce que je voulais cette fonctionnalité pour transférer des systèmes de fichiers entiers, et /usr semblait être un bon échantillon représentatif.

Le --info=progress2 donne un bon pourcentage global, même s'il ne s'agit que d'une valeur partielle. En fait, mon /usr le dossier compte plus de 6 concerts:

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

et rsync a pris beaucoup de temps pour tout analyser. Donc, presque tout le temps, le pourcentage que j'ai vu était terminé à environ 90%, mais il est néanmoins réconfortant de voir que quelque chose est copié :)

Références:

409
Avio

Vous pouvez avec 'pv' (apt-get install pv avec Debian et ubuntu). Je recommande de surveiller le nombre de fichiers transférés, car la quantité de données transférées n'est pas corrélée à la taille des fichiers mais sur le delta entre la source et la destination. Et compter les fichiers comptera la même progression pour un grand delta et un autre avec un petit delta. Ce qui signifie que dans tous les cas, l'estimation ETA pourrait être loin. L'ETA basé sur la taille ne fonctionne que si votre destination est vide, dans ce cas delta == taille de la source.

L'idée générale est d'émettre une ligne par fichier "transféré" depuis rsync et de compter ces lignes avec "pv":

 rsync -ai/source distant:/dest | pv -les [nombre de fichiers]>/dev/null 

J'ai tendance à sauvegarder des systèmes de fichiers entiers (pour plusieurs raisons), dans ce cas, vous pouvez utiliser le df beaucoup moins cher pour obtenir le nombre de fichiers (plutôt que du ou find wich traversera votre hiérarchie source une autre fois après que rsync l'ait fait). L'option -x apparaît pour s'assurer que rsync reste sur le même système de fichiers source (et ne suit pas les autres montages internes):

 rsync -aix/source distante:/dest | pv -les $ (df -i/source | Perl -ane 'affiche $ F [2] si $ F [5] = ~ m: ^ /:')>/dev/null 

Si vous souhaitez compter les fichiers dans/source de manière générale, utilisez find /source|wc -l (avertissement à nouveau: peut être lent et lourd sur les E/S).

48
zerodeux

Ce qui suit s'applique à rsync version 3.0.0 et supérieure. Les options décrites ci-dessous ont été introduites dans cette version le 1er mars 2008.

Avec - info = progress2 , vous pouvez également utiliser - no-inc-recursive option (ou son alias plus court - no-ir ) pour désactiver la récursivité incrémentielle.

Cela créera la liste complète des fichiers au début, plutôt que de découvrir progressivement plus de fichiers au fur et à mesure du transfert. Puisqu'il connaîtra tous les fichiers avant de commencer, il donnera un meilleur rapport de la progression globale. Cela s'applique au nombre de fichiers - il ne signale aucune progression en fonction de la taille des fichiers.

Cela implique un compromis. La création de la liste complète des fichiers à l'avance est plus coûteuse en mémoire et peut retarder considérablement le début du transfert réel. Comme vous vous en doutez, plus il y a de fichiers, plus le délai sera long et plus il faudra de mémoire.

Ce qui suit provient du manuel rsync (source - http://rsync.samba.org/ftp/rsync/rsync.html ):

- r, - récursif

Cela indique à rsync de copier les répertoires de manière récursive. Voir aussi --dirs (-d). À partir de rsync 3.0.0, l'algorithme récursif utilisé est maintenant une analyse incrémentielle qui utilise beaucoup moins de mémoire qu'auparavant et commence le transfert une fois l'analyse des premiers répertoires terminée. Cette analyse incrémentielle affecte uniquement notre algorithme de récursivité et ne modifie pas un transfert non récursif. Il n'est également possible que lorsque les deux extrémités du transfert sont au moins la version 3.0.0.

Certaines options nécessitent rsync pour connaître la liste complète des fichiers, donc ces options désactivent le mode de récursivité incrémentielle. Ceux-ci incluent: --delete-before, --delete-after, --Prune-empty-dirs et --delay-updates. Pour cette raison, le mode de suppression par défaut lorsque vous spécifiez --delete est désormais --delete-during lorsque les deux extrémités de la connexion sont au moins 3.0.0 (utilisez --del ou --delete-during pour demander ce mode de suppression amélioré explicitement). Voir aussi l'option --delete-delay qui est un meilleur choix que d'utiliser --delete-after.

La récursivité incrémentielle peut être désactivée à l'aide de l'option - no-inc-recursive ou de sa plus courte - no-ir alias.

Voir aussi https://rsync.samba.org pour les différences de version spécifiques (faites défiler vers le bas et consultez les liens Release News).

40
Nate

danakim a raison. Il n'y a aucun moyen trivial d'ajouter un indicateur de progression totale.

La raison en est que lorsque rsync examine une liste de fichiers à synchroniser, il ne sait pas à l'avance quels fichiers devront être modifiés. Si vous effectuez des transferts delta, les deltas eux-mêmes doivent être calculés à l'avance pour donner une image globale du travail à effectuer.

En d'autres termes, la façon la plus simple de calculer la quantité de travail à faire est de le faire réellement.

37
David Mackintosh

Pour les longs transferts, je suis content de courir du -s sur les deux côtés. Même watch -n1 du -s, si je me sens vraiment anxieux.

watch exécute une commande (du -s ici) périodiquement (toutes les 1 seconde ici) et affiche la sortie en plein écran.

29
funollet

En gros non. Vous ne pouvez afficher la progression par fichier qu'avec l'indicateur --progress, mais c'est tout.

Je suppose que vous pouvez écrire un wrapper autour de lui ou utiliser l'un des correctifs que vous trouvez déjà, mais vous devez vous demander si cela en vaut vraiment la peine, avez-vous réellement besoin d'une progression totale pour rsync?

13
danakim

J'ai utilisé la réponse de zerodeux et écrit mon propre petit 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=$(${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"
8
FloHallo

J'ai également cherché comment afficher la progression totale avec rsync et j'ai trouvé une réponse utile à partir de ce post: https://stackoverflow.com/questions/7157973/monitoring-rsync-progress

Fondamentalement, vous pouvez utiliser - info = progress2 dans la version de développement de rsync 3.1.0 . Voici ce que le doc a dit:

Il existe également une option --info = progress2 qui génère des statistiques basées sur l'ensemble du transfert, plutôt que sur des fichiers individuels. Utilisez cet indicateur sans sortir un nom de fichier (par exemple, évitez -v ou spécifiez --info = nom0 si vous voulez voir comment se déroule le transfert sans faire défiler l'écran avec beaucoup de noms. (Vous n'avez pas besoin de spécifier le - option de progression pour utiliser --info = progress2.)

7
Zhenyi Zhang

Si vous n'avez pas la dernière version de rsync (par exemple, OS X a 2.6.9) et ne pouvez pas utiliser --info=progress2, voici une autre alternative pour vous sauver des pages de texte défilant sur la progression:

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

Cela affichera, sur une ligne, le nom du dernier fichier transféré:

Transferring: the-latest.file

6
Aral Balkan

J'ai utilisé la réponse de zerodeux et écrit mon propre petit 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"

J'ai changé le TODO dry-run en

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

Il trouve le nombre de fichiers très rapidement!

6
user151779

J'en ferais un commentaire mais je n'ai pas assez de réputation. En réponse au commentaire de naught101 sur la réponse choisie, l'option --progress indique le nombre de fichiers transférés sur le montant total à transférer. Je ne l'ai pas réalisé avant de regarder ce post et de regarder la sortie plus attentivement.

La statistique "à vérifier" montre combien de fichiers sont laissés en dehors du total. Ceci est très utile lors de la synchronisation avec une nouvelle destination afin que vous sachiez que tous les fichiers seront entièrement copiés.

Depuis la page de manuel:

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.
4
Michael S

Utilisation

lsof -ad3-999 -c rsync

Pour voir quels fichiers rsync a actuellement ouverts (montrera la taille du fichier) rsync copie localement dans un fichier caché

4
Cloom Magoo

Notez la mise en garde ici que même --info = progress2 n'est pas entièrement fiable car ce pourcentage est basé sur le nombre de fichiers que rsync "connaît" au moment où la progression est affichée. Ce n'est pas nécessairement le nombre total de fichiers qui devaient être synchronisés (par exemple, s'il découvre un grand nombre de fichiers volumineux dans un répertoire profondément imbriqué). Une façon de s'assurer que --info = progress2 ne "saute pas" dans l'indication de progression serait de forcer rsync à analyser tous les répertoires de manière récursive avant de démarrer la synchronisation (au lieu de son comportement par défaut consistant à effectuer une analyse récursive incrémentielle), en fournissant également l'option --no-inc-récursive. Notez cependant que cette option augmentera également l'utilisation de la mémoire rsync et l'exécution.

3
lonetwin

J'utilise un script qui extrait les informations de/proc // io pour le processus rsync (ou tout autre processus d'ailleurs) et sachant le montant total à transférer est calculé la progression.

#!/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 -------------------------------------------------------------------"
2
nito

Si votre version de rsync n'accepte pas le --info=progress2 option, vous pouvez utiliser tqdm :

À installer:

pip install tqdm

Utiliser:

 $ rsync -av/source/dest | tqdm --unit_scale | wc -l 
 10,0Mit [00:02, 3,58Mit/s] 
2
ostrokach

Vous pouvez peut-être combiner pv avec rsync. En particulier, le paramètre --size Pourrait être utile. En jetant un œil aux documents, quelque chose comme pv --size $(du -sb . | awk '{print $1}') | rsync -av . Host:/your/path devrait fonctionner.

Ici vous trouverez les documents et les logiciels.

Je n'ai pas essayé ça tout seul.

1
Christian

Peut-être un peu tard ici, mais les futurs chercheurs de réponses pourraient en bénéficier.

Cela me dérangeait aussi, alors j'ai pensé que je serais déprimé et que j'écrirais mon premier script. Le paquet zenity doit être installé (Sudo apt-get install zenity), mais je suis sûr qu'il sera probablement déjà là. En outre, j'utilise wmctrl (contrôle du gestionnaire de fenêtres) pour changer le titre de la boîte de dialogue de progression une fois terminé, il est facilement installable mais ne fera pas de différence si vous ne le faites pas. J'aime juste voir quand c'est fait dans mon panel.

Le script demande essentiellement un répertoire source et destination, calcule le pourcentage de la destination sur la source en taille en utilisant du et affiche une barre de progression.

Remarque: Cela ne fonctionne que pour la synchronisation complète du répertoire/fichier (je l'utilise généralement pour faire des sauvegardes du cache apt), donc pas d'option --exclude =/file/in/Source-directory. Ne fonctionnera pas non plus s'il y a des fichiers/répertoires dans le répertoire de destination et non dans le répertoire source. Je ne sais pas si cela fonctionne pour les sources/destinations distantes, car je n'en ai jamais eu besoin ni les ressources pour le tester.

PS. Ce script peut être très mal écrit ou très inefficace, (vierge de script ici), mais au moins il remplit sa fonction et bien sûr, vous pouvez le modifier et l'améliorer en fonction de vos besoins. PSS. De plus, je n'ai pas pu obtenir le bouton d'annulation pour tuer rsync, je l'ai donc supprimé.

    #!/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
1
neill_L