Назад | Перейти на главную страницу

Отображение общего прогресса в rsync: возможно ли это?

Я уже искал этот вариант, но нашел только решения, которые включают пользовательское исправление. Тот факт, что он не отображается в --help и больше информации не может быть найден, вероятно, указывает на то, что ответ - «нет», но я бы хотел, чтобы это подтвердилось.

Можно ли показать общий прогресс передачи файлов с rsync?

Теперь есть официальный способ сделать это в rsync (версия протокола 3.1.0 версии 31, протестировано с 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)

Я пробовал с моим /usr папку, потому что мне нужна эта функция для передачи целых файловых систем, и /usr казался хорошей репрезентативной выборкой.

В --info=progress2 дает хороший общий процент, даже если это всего лишь частичное значение. На самом деле мой /usr папка больше 6 гигов:

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

и rsync на сканирование всего этого ушло много времени. Так что почти все время процент, который я видел, был выполнен примерно на 90%, но, тем не менее, приятно видеть, что что-то копируется :)

Ссылки:

Следующее относится к версии rsync 3.0.0 и выше. Описанные ниже параметры были представлены в этом выпуске 1 марта 2008 г.

Вместе с --info = прогресс2 вы также можете использовать --no-inc-recursive вариант (или его короче - нет-я-р псевдоним), чтобы отключить инкрементную рекурсию.

Это создаст весь список файлов в начале, а не будет постепенно обнаруживать новые файлы по мере продолжения передачи. Поскольку он будет знать все файлы перед запуском, он будет лучше сообщать об общем прогрессе. Это относится к количеству файлов - он не сообщает о прогрессе, основанном на размерах файлов.

Это предполагает компромисс. Предварительное создание всего списка файлов требует больших затрат памяти и может значительно задержать начало фактической передачи. Как и следовало ожидать, чем больше файлов будет, тем больше будет задержка и тем больше памяти потребуется.

Следующее - из руководства rsync (источник - http://rsync.samba.org/ftp/rsync/rsync.html ):

-r, --recursive

Это указывает rsync рекурсивно копировать каталоги. Смотрите также --dirs (-d). Начиная с rsync 3.0.0, рекурсивный алгоритм теперь представляет собой инкрементное сканирование, которое использует гораздо меньше памяти, чем раньше, и начинает передачу после того, как сканирование первых нескольких каталогов было завершено. Это инкрементное сканирование влияет только на наш алгоритм рекурсии и не меняет нерекурсивную передачу. Это также возможно только тогда, когда оба конца передачи имеют версию не ниже 3.0.0.

Некоторые параметры требуют, чтобы rsync знал полный список файлов, поэтому эти параметры отключают режим инкрементной рекурсии. К ним относятся: --delete-before, --delete-after, --prune-empty-dirs и --delay-updates. Из-за этого режим удаления по умолчанию, когда вы указываете --delete, теперь --delete-during, когда оба конца соединения имеют значение не менее 3.0.0 (используйте --del или --delete-during, чтобы запросить этот улучшенный режим удаления явно). См. Также параметр --delete-delay, который лучше, чем использование --delete-after.

Инкрементную рекурсию можно отключить с помощью --no-inc-recursive вариант или его короче - нет-я-р псевдоним.

Смотрите также https://rsync.samba.org для конкретных различий в версиях (прокрутите вниз и проверьте ссылки Release News).

Вы можете с 'pv' (apt-get install pv с Debian и ubuntu). Я рекомендую следить за количеством переданных файлов, поскольку объем передаваемых данных зависит не от размера файлов, а от разницы между источником и местом назначения. И при подсчете файлов будет учитываться один и тот же прогресс для одной большой дельты и другой с маленькой дельтой. Это означает, что в любом случае оценка ETA может быть далекой. ETA на основе размера работает только в том случае, если ваш пункт назначения пуст, в этом случае delta == size of source.

Общая идея состоит в том, чтобы выдавать одну строку для каждого файла, "переданного" из rsync, и считать эти строки с помощью "pv":

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

Я стараюсь создавать резервные копии целых файловых систем (по нескольким причинам), в этом случае вы можете использовать гораздо более дешевый df чтобы получить количество файлов (а не du или find который будет пересекать вашу исходную иерархию в другой раз после того, как это сделает rsync). Параметр -x, по-видимому, гарантирует, что rsync остается в той же исходной файловой системе (и не следует за другими внутренними установками):

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

Если вы хотите подсчитать файлы в / source в общем случае, используйте find /source|wc -l (еще раз предупреждение: может быть медленным и тяжелым при вводе-выводе).

данаким правильный. Нет тривиальных способов добавить индикатор общего прогресса.

Причина этого в том, что когда rsync просматривает список файлов для синхронизации, он не знает заранее, какие файлы нужно будет изменить. Если вы выполняете дельта-переводы, сами дельты должны быть рассчитаны заранее, чтобы дать общую картину работы, которую необходимо выполнить.

Другими словами, самый простой способ подсчитать, сколько работы предстоит сделать, - это действительно ее выполнить.

Для длительных переездов доволен бегом du -s с обеих сторон. Четный watch -n1 du -s, если я действительно беспокоюсь.

watch выполняет команду (du -s здесь) периодически (здесь каждую 1 секунду) и показывает вывод в полноэкранном режиме.

В основном нет. Вы можете показать прогресс для каждого файла только с флагом --progress, но это все.

Я предполагаю, что вы можете написать обертку вокруг него или использовать какие-либо патчи, которые вы уже нашли, но вы должны спросить себя, действительно ли это того стоит, вам действительно нужен полный прогресс для rsync?

Я также искал, как показать общий прогресс с rsync, и нашел полезный ответ из этого сообщения: https://stackoverflow.com/questions/7157973/monitoring-rsync-progress

В основном вы можете использовать --info = прогресс2 в версии rsync для разработчиков 3.1.0. Вот что док сказал:

Также есть опция --info = progress2, которая выводит статистику на основе всей передачи, а не отдельных файлов. Используйте этот флаг без вывода имени файла (например, избегайте -v или укажите --info = name0, если вы хотите увидеть, как происходит передача, не прокручивая экран с большим количеством имен. (Вам не нужно указывать - прогресс, чтобы использовать --info = progress2.)

Я использовал ответ от zerodeux и написал свой собственный небольшой скрипт на 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"

Если у вас нет последней версии rsync (например, в OS X 2.6.9) и вы не можете использовать --info=progress2, вот еще одна альтернатива, чтобы избавиться от страниц с прокручивающимся текстом по мере продвижения:

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

Это напечатает в одной строке имя последнего передаваемого файла:

Transferring: the-latest.file

Я использовал ответ от zerodeux и написал свой собственный небольшой сценарий 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"

Я изменил пробный прогон TODO на

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

Он очень быстро находит количество файлов!

Я бы сделал это замечание, но у меня недостаточно репутации. В ответ на комментарий naught101 к выбранному ответу опция --progress показывает, сколько файлов было передано из общей суммы для передачи. Я не осознавал этого, пока не посмотрел этот пост и не посмотрел на результат более внимательно.

Статистика «для проверки» показывает, сколько файлов осталось из общего числа. Это наиболее полезно при rsync'е в новое место назначения, чтобы вы знали, что все файлы будут полностью скопированы.

На странице руководства:

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.

Использовать

lsof -ad3-999 -c rsync

Чтобы увидеть, какие файлы rsync в настоящее время открыты (будет отображаться размер файла), rsync копирует локально в скрытый файл

Обратите внимание на предостережение здесь, что даже --info = progress2 не совсем надежен, поскольку это процентное соотношение, основанное на количестве файлов, о которых rsync "знает" в то время, когда отображается прогресс. Это не обязательно общее количество файлов, которые необходимо синхронизировать (например, если обнаружено большое количество больших файлов в глубоко вложенном каталоге). Один из способов гарантировать, что --info = progress2 не «перескакивает» в индикатор выполнения, - это заставить rsync рекурсивно сканировать все каталоги перед запуском синхронизации (вместо его поведения по умолчанию, заключающегося в выполнении инкрементно-рекурсивного сканирования), также предоставив параметр --no-inc-recursive. Однако обратите внимание, что этот параметр также увеличит использование памяти и время выполнения rsync.

Если ваша версия rsync не принимает --info=progress2 вариант, вы можете использовать tqdm:

Установить:

pip install tqdm

Использовать:

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

Я использую сценарий, который извлекает информацию из / proc // io для процесса rsync (или любого другого процесса, если на то пошло), и зная, что общая сумма, подлежащая передаче, вычисляет прогресс.

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

Возможно, вы сможете совместить pv с помощью rsync. Особенно параметр --size может быть полезным. Взглянув на документы, что-то вроде pv --size $(du -sb . | awk '{print $1}') | rsync -av . host:/your/path должно сработать.

Вот вы найдете документацию и программное обеспечение.

Сам не пробовал.

Может быть, здесь немного поздно, но будущие ищущие ответы могут выиграть.

Меня это тоже беспокоило, поэтому я подумал, что займусь грязью и напишу свой первый сценарий. Необходимо установить пакет zenity (sudo apt-get install zenity), но я уверен, что он, вероятно, уже будет там. Кроме того, я использую wmctrl (элемент управления оконным менеджером), чтобы изменить заголовок диалогового окна выполнения, когда это будет сделано, его легко установить, но если вы этого не сделаете, это не изменит ситуацию. Мне просто нравится видеть, когда это делается на моей панели.

Сценарий в основном запрашивает исходный и целевой каталог, вычисляет процентное соотношение конечного пункта по размеру источника с использованием du и отображает индикатор выполнения.

Примечание: это работает только для полной синхронизации каталогов / файлов (я обычно использую его для создания резервных копий кеша apt), поэтому нет опции --exclude = / file / in / Source-directory. Также не будет работать, если в целевом каталоге есть файлы / каталоги, а не в исходном каталоге. Я не уверен, работает ли он для удаленных источников / пунктов назначения, поскольку у меня никогда не было необходимости в нем или ресурсов для его тестирования.

PS. Этот сценарий может быть очень плохо написан или очень неэффективен (здесь script-virgin), но, по крайней мере, он служит своей цели, и, конечно, вы можете редактировать и улучшать его в соответствии с вашими потребностями. PSS. Кроме того, не удалось заставить кнопку отмены убить rsync, поэтому я просто удалил ее.

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