Вопрос или проблема
Я уже искал эту опцию, но нашёл только решения, которые включают в себя кастомные патчи. То, что это не отображается в –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=progress2 вы также можете использовать –no-inc-recursive (или её короткий –no-i-r вариант), чтобы отключить инкрементальную рекурсию.
Это создаст весь список файлов в начале, а не будет инкрементально обнаруживать больше файлов по мере передачи. Поскольку он будет знать все файлы перед началом, он даст лучший отчет о общем прогрессе. Это применимо к количеству файлов — оно не сообщает о прогрессе, основанном на размерах файлов.
Это связано с необходимостью компромисса. Создание всего списка файлов заранее требует больше памяти и может значительно задержать начало фактической передачи. Как вы могли ожидать, чем больше файлов, тем дольше будет задержка и тем больше памяти потребуется.
Следующее взято из руководства 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 или её короткий –no-i-r вариант.
Смотрите также https://rsync.samba.org для конкретных различий версий (прокрутите вниз и посмотрите ссылки на Release News).
Вы можете использовать ‘pv’ (apt-get install pv
с Debian и Ubuntu). Я рекомендую отслеживать количество переданных файлов, так как объем передаваемых данных не связан с размером файлов, а зависит от разницы между источником и приемником. Подсчет файлов будет одинаково отслеживать прогресс как для одного большого дельта, так и для другого с маленьким дельта. Это означает, что в любом случае оценка ETA может быть далеко от истинного значения. Оценка на основе размера работает только если ваш приемник пуст, в этом случае дельта == размер источника.
Общая идея состоит в том, чтобы выводить одну строку на файл ‘переносимый’ от rsync и подсчитывать эти строки с помощью ‘pv’:
rsync -ai /source remote:/dest | pv -les [количество файлов] >/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
(предупреждение: это может быть медленно и тяжело для I/O).
danakim прав. Нет тривиальных способов добавить индикатор общего прогресса.
Причина этого в том, что когда rsync смотрит на список файлов для синхронизации, он не знает заранее, какие файлы нужно будет изменить. Если вы делаете дельта-передачи, сами дельты должны быть рассчитаны заранее, чтобы дать полное представление о работе, которую необходимо выполнить.
Иными словами, самый простой способ рассчитать, сколько работы нужно сделать, — это на самом деле это сделать.
Для длительных передач я рад запустить du -s
с обеих сторон. Даже watch -n1 du -s
, если я чувствую себя действительно тревожным.
watch
выполняет команду (du -s
здесь) периодически (каждую 1 секунду) и отображает результат на весь экран.
Почти нет. Вы можете показывать только прогресс по файлам с помощью флага –progress, но это почти всё.
Я предполагаю, что вы можете написать обертку вокруг него или использовать любой из патчей, которые вы уже нашли, но вам стоит спросить себя, действительно ли это того стоит, действительно ли вам нужен общий прогресс для rsync?
Я также искал, как показать общий прогресс с rsync и нашёл полезный ответ из этого поста: https://stackoverflow.com/questions/7157973/monitoring-rsync-progress
В основном, вы можете использовать –info=progress2 в дев-версии rsync 3.1.0. Вот что написано в документации:
Есть также опция –info=progress2, которая выводит статистику на основе всей передачи, а не отдельных файлов. Используйте этот флаг без вывода имени файла (например, избегайте -v или указывайте –info=name0, если хотите видеть, как идет передача, не прокручивая экран с множеством имен. (Не нужно указывать опцию –progress, чтобы использовать –info=progress2.)
Используйте
lsof -ad3-999 -c rsync
Чтобы увидеть, какие файлы rsync в данный момент открывает (покажет размер файла) rsync копирует в скрытый файл локально
Я воспользовался ответом от zerodeux и написал свой собственный небольшой bash-скрипт:
#!/bin/bash
RSYNC="ionice -c3 rsync"
# не используйте --progress
RSYNC_ARGS="-vrltD --delete --stats --human-readable"
SOURCES="/dir1 /dir2 /file3"
TARGET="storage::storage"
echo "Выполняется проверка, чтобы увидеть, сколько файлов должно быть передано..."
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"
# не используйте --progress
RSYNC_ARGS="-vrltD --delete --stats --human-readable"
SOURCES="/dir1 /dir2 /file3"
TARGET="storage::storage"
#echo "Выполняется проверка, чтобы увидеть, сколько файлов должно быть передано..."
TODO=$(find ${SOURCES} | wc -l)
${RSYNC} ${RSYNC_ARGS} ${SOURCES} ${TARGET} | pv -l -e -p -s "$TODO"
Я изменил проверку TODO на
TODO=$(find ${SOURCES} | wc -l)
Это быстро находит количество файлов!
Я создал индикатор прогресса для rsync в виде обертки. С --info=progress2
из новых версий rsync патчирование не требуется.
Используйте — замените rsync
на rsyncy
:
rsyncy -a FROM/ TO
Больше информации на GitHub, установить с помощью pip3 install --user rsyncy
Обратите внимание на то, что даже –info=progress2 не совсем надежен, так как этот процент основан на количестве файлов, о которых rsync ‘знает’ на момент отображения прогресса. Это не обязательно общее количество файлов, которые нужно синхронизировать (например, если он обнаруживает большое количество больших файлов в глубоко вложенной директории). Одним из способов обеспечения того, чтобы –info=progress2 не ‘подскакивал назад’ в показании прогресса, было бы заставить rsync просканировать все директории рекурсивно перед началом синхронизации (вместо его стандартного поведения по выполнению инкрементального рекурсивного сканирования), предоставив также опцию –no-inc-recursive. Однако имейте в виду, что эта опция также увеличит использование памяти и время выполнения rsync.
Я бы сделал это комментарием, но у меня недостаточно репутации. В ответ на комментарий naught101 к выбранному ответу опция –progress показывает, сколько файлов было передано из общего количества для передачи. Я не осознавал этого, пока не посмотрел на этот пост и не рассмотрел вывод более внимательно.
Статистика ‘to-check’ показывает, сколько файлов осталось из общего. Это наиболее полезно, когда вы rsync’ите на новое назначение, чтобы знать, что все файлы будут полностью скопированы.
Из страницы man:
Когда [каждая] передача файла завершается, rsync заменяет строку прогресса на строку сводки, которая выглядит так:
1238099 100% 146.38kB/s 0:00:08 (xfer#5, to-check=169/396)
В этом примере файл имел общий размер 1238099 байт, средняя скорость передачи для всего файла составила 146.38 килобайта в секунду за 8 секунд, которые потребовались для завершения, это была 5-я передача обычного файла во время текущей сессии rsync, и осталось 169 файлов для проверки получателя (чтобы проверить, являются ли они актуальными или нет) из 396 файлов в общем списке файлов.
Я использую скрипт, который извлекает информацию из /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 "Ожидание появления процесса с PID=$PID!"
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 "Мониторинг PID: $PID"
echo
echo "Чтение: $BL_READ MiB за $TLOOP с"
echo "Запись: $BL_WRITE MiB за $TLOOP с"
echo
echo "Скорость чтения: $R_SPEED MiB/c ( средняя: $R_SPEED_AVG, максимум: $R_SPEED_MAX )"
echo "Скорость записи: $W_SPEED MiB/c ( средняя: $W_SPEED_AVG, максимум: $W_SPEED_MAX )"
echo
echo "Готово: $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 "Прошло времени: `ps -p $PID -o etime=`"
T1=`date +%s.%N`
sleep $DELAY
B_READ_PREV=$B_READ
B_WRITE_PREV=$B_WRITE
((count++))
done
echo "----- Завершено -------------------------------------------------------------------"
Если ваша версия rsync
не принимает опцию --info=progress2
, вы можете использовать tqdm
:
Для установки:
pip install tqdm
Для использования:
$ rsync -av /source /dest | tqdm --unit_scale | wc -l 10.0Mit [00:02, 3.58Mit/s]
Возможно, вы можете объединить 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. Этот скрипт может быть очень плохо написан или очень неэффективен (я новичок в скриптах), но, по крайней мере, он выполняет свою задачу, и, конечно, вам добро пожаловать редактировать и улучшать его в соответствии с вашими потребностями. PSS. Я также не смог заставить кнопку отмены завершить rsync, поэтому я просто убрал её.
#!/bin/bash
set -e;
WELC="Запуск RsyncP от имени $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="Синхронизация файлов завершена!";
}
function get_input()
{
dirs=$(zenity --forms --width=500 --title="RsyncP" --text="Введите исходные и целевые каталоги" --add-entry="Источник: " --add-entry="Назначение: " --separator=" ");
SOURCE_FOLDER=$(echo $dirs | cut -d' ' -f 1);
DEST_FOLDER=$(echo $dirs | cut -d' ' -f 2);
OPTIONS=-$(zenity --list --title="RsyncP Options" --text="Выберите параметры rsync" --separator="" --height=470 --width=470 --checklist --column "активировать" --column "Опция" --column "Описание" FALSE v "Подробно (только терминал)" FALSE q "Скрыть, подавить неошибочные сообщения (только терминал)" FALSE P "Прогресс (только терминал)" FALSE a "Архив (lrpog)" TRUE r "Рекурсивно в директориях" FALSE p "Сохранять права" FALSE o "Сохранять владельца" FALSE g "Сохранять группу" FALSE l "Копировать символьные ссылки как символьные ссылки");
zenity --question --no-wrap --title="RsyncP" --width=500 --text="rsync $OPTIONS $SOURCE_FOLDER $DEST_FOLDER\nВы хотите продолжить?";
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, Продолжить?";
get_input;
rsync $OPTIONS $SOURCE_FOLDER $DEST_FOLDER &
echo_progress | zenity --progress --title=RsyncP --no-cancel --auto-close --text="Копирование из \n$SOURCE_FOLDER в \n$DEST_FOLDER" ;
else
zenity --question --title=RsyncP --text="$WELC, Продолжить?";
get_input;
sudo rsync $OPTIONS $SOURCE_FOLDER $DEST_FOLDER &
echo_progress | zenity --progress --title=RsyncP --no-cancel --auto-close --text="Копирование из \n$SOURCE_FOLDER в \n$DEST_FOLDER" ;
fi
Если у вас нет последнего rsync (например, в OS X стоит 2.6.9) и вы не можете обновить с помощью brew upgrade rsync, вам не нужно использовать –info=progress2, или другой альтернативой вы можете увидеть вывод файлов без дополнительных команд:
rsync -avh
–info=progress2 работает хорошо
если вам нужно добавить данные, тогда, на мой взгляд, удобно сначала отображать максимальный процент
#!/bin/bash
SOURCE=a
TARGET=b
TMP_F=/tmp/rsync.log
PARAMS="--info=progress2 --stats -r -tgo -p -l --update -H $SOURCE $TARGET"
display_total_copy_persent() {
rsync --dry-run $PARAMS > $TMP_F
total=`grep "^Total file size" $TMP_F | awk '{print $4}' | tr -d ','`
trans=`grep "^Total transferred file size" $TMP_F | awk '{print $5}' | tr -d ','`
if [ $total != 0 ]; then persent=$(($trans/($total/100))); fi
printf "\033[0;32m[##################################################]\033[0m\n"
printf "\033[0;32m[ Будет скопировано = \033[0;34m$persent%%\033[0;30m ]\n"
printf "\033[0;32m[##################################################]\033[0m\n"
}
start_rsync_progress() {
rsync $PARAMS
}
display_total_copy_persent
start_rsync_progress
> rsync --info=help
Используйте OPT или OPT1 для вывода уровня 1, OPT2 для уровня 2 и т.д.; OPT0 отключает.
BACKUP Упоминание файлов, которые были сохранены
COPY Упоминание файлов, скопированных локально на стороне получения
DEL Упоминание удалений на стороне получения
FLIST Упоминание списка файлов, получаемых/отправляемых (уровни 1-2)
MISC Упоминание разнообразной информации (уровни 1-2)
MOUNT Упоминание монтирований, которые были найдены или пропущены
NAME Упоминание 1) обновленных имен файлов/директорий, 2) неизмененных имен
NONREG Упоминание пропущенных нерегулярных файлов (значение по умолчанию 1, 0 отключает)
PROGRESS Упоминание 1) прогресса по файлам или 2) общего прогресса передачи
REMOVE Упоминание файлов, удалённых на стороне отправки
SKIP Упоминание файлов, пропущенных из-за переопределений передачи (уровни 1-2)
STATS Упоминание статистики в конце выполнения (уровни 1-3)
SYMSAFE Упоминание небезопасных символических ссылок
ALL Установить все --info опции (например, all4)
NONE Тишина всех --info опций (то же, что и all0)
HELP Вывод этого справочного сообщения
Опции, добавляемые на каждом уровне детализации:
0) NONREG
1) COPY,DEL,FLIST,MISC,NAME,STATS,SYMSAFE
2) BACKUP,MISC2,MOUNT,NAME2,REMOVE,SKIP
Таким образом, rsync --info=progress2
кажется наиболее разумным
Ответ или решение
Да, показывать общий прогресс при использовании rsync
теперь возможно благодаря опции --info=progress2
, которая была добавлена в версии 3.1.0. Эта опция выводит общую информацию о прогрессе переданных данных, вместо отображения прогресса для каждого отдельного файла.
Вот как можно использовать эту опцию:
rsync -a --info=progress2 /source /destination
При выполнении этой команды вы получите строку с процентом завершения, средней скоростью передачи и оставшимся временем. Например, вывод может выглядеть так:
305,002,533 80% 65.69MB/s 0:00:01 xfr#1653, ir-chk=1593/3594
Дополнительные рекомендации
-
Опция
--no-inc-recursive
: Чтобы улучшить точность отображаемого прогресса, можно использовать опцию--no-inc-recursive
, которая отключает инкрементную рекурсию. Это позволитrsync
сначала составить полный список файлов, что даст более точный отчет о прогрессе, но увеличит потребление памяти и время начала передачи. Пример использования:rsync -a --info=progress2 --no-inc-recursive /source /destination
-
Альтернативные подходы: Если у вас старая версия
rsync
, не поддерживающая--info=progress2
, вы можете использовать сторонние утилиты, такие какpv
(Pipe Viewer) илиtqdm
. Например, следующим образом:rsync -a /source /destination | pv -s $(du -sb /source | awk '{print $1}') > /dev/null
Либо, используя
tqdm
:rsync -av /source /destination | tqdm --unit_scale | wc -l
Заключение
Таким образом, с помощью опции --info=progress2
в rsync
вы можете получить общее отображение прогресса при выполнении сложных операций по синхронизации файлов. Это полезный инструмент, особенно при работе с большими объемами данных или при резервном копировании целых файловых систем.
Для получения дополнительной информации о других доступных опциях вы можете обратиться к официальной документации rsync
, доступной по адресу rsync(1) man page.