Answers:
danakim是正确的。没有简单的方法可以添加总进度指示器。
原因是当rsync查看要同步的文件列表时,它不预先知道需要更改哪些文件。如果您要进行增量传输,则必须提前计算增量本身,以全面了解需要完成的工作。
换句话说,计算要做多少工作的最简单方法是实际完成。
--size-only
或类似内容的答案更加不准确。
现在,在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%,但尽管如此,看到正在复制的内容还是令人欣慰的:)
参考文献:
--info=progress2
不起作用-v
--no-i-r
开关,因此rsync
在复制之前不会进行增量扫描,而是完全扫描,并且知道并显示剩余的工作量。
--human-readable
(或-h
)查看正在进行的总大小(MB / GB)。
您可以使用'pv'(apt-get install pv
与Debian和ubuntu一起使用)。我建议监视传输的文件数,因为传输的数据量与文件的大小无关,而与源和目标之间的增量有关。对文件进行计数将对一个大增量和另一个小增量进行相同的计数。这意味着在任何情况下ETA估计都可能相差甚远。基于大小的ETA仅在目的地为空时才有效,在这种情况下,增量==源大小。
一般的想法是从rsync'传输'的每个文件发出一行,并用'pv'计算这些行:
rsync -ai /源远程:/目的地| pv -les [文件数]> / dev / null
我倾向于备份整个文件系统(出于几个原因),在这种情况下,您可以使用便宜得多df
的文件来获取文件的数量(而不是du
或find
夹到rsync之后再遍历源层次结构)。出现-x选项以确保rsync停留在相同的源文件系统上(并且不跟随其他内部安装):
rsync -aix /源远程:/目的地| pv -les $(df -i / source | perl -ane'如果$ F [5] =〜m:^ /:'print $ F [2])> / dev / null
如果要以常规方式对/ source中的文件进行计数,请使用find /source|wc -l
(再次警告:可能会使I / O变得缓慢而繁琐)。
df -i /source
它从/ source所在的所有分区中获取索引节点(文件)的数量。否则,使用“ find”对 “ $()”表达式内目录中的文件进行计数。
du
或者的替代方法find
-假设您要完成不完整的副本或使用rsync -ai --dry-run
pv
以下内容适用于rsync 3.0.0及更高版本。下列选项在2008年3月1日的发行版中引入。
与--info = progress2一起,您还可以使用--no-inc-recursive选项(或更短的--no-ir别名)来禁用增量递归。
这将在开始时构建整个文件列表,而不是随着传输的进行逐渐发现更多文件。由于它将在启动之前知道所有文件,因此它将为整体进度提供更好的报告。这适用于文件数量-它不会根据文件大小报告任何进度。
这涉及权衡。提前构建整个文件列表会消耗更多的内存,并且会大大延迟实际传输的开始。如您所料,文件越多,延迟时间就越长,所需的内存就越多。
以下来自rsync手册(源-http : //rsync.samba.org/ftp/rsync/rsync.html):
-r,-递归
这告诉rsync递归复制目录。另请参见--dirs(-d)。从rsync 3.0.0开始,现在使用的递归算法是增量扫描,它使用的内存比以前少得多,并在扫描完头几个目录后开始传输。这种增量扫描只会影响我们的递归算法,而不会更改非递归传输。仅当传输的两端至少为3.0.0版本时,才有可能。
一些选项要求rsync知道完整的文件列表,因此这些选项禁用增量递归模式。其中包括:--delete-before,--delete-after,--prune-empty-dirs和--delay-updates。因此,当连接的两端至少为3.0.0时,指定--delete时的默认删除模式现在为--delete-during(请使用--del或--delete-during请求此改进的删除模式明确地)。另请参见--delete-delay选项,它比使用--delete-after更好。
可以使用--no-inc-recursive选项或其较短的--no-ir别名禁用增量递归。
另请参阅https://rsync.samba.org以获取特定版本差异(向下滚动并查看Release News链接)。
对于长距离转会,我很高兴能du -s
在双方上奔跑。即使watch -n1 du -s
,如果我真的很着急。
watch
du -s
定期(此处每1秒)执行一次命令(此处),并全屏显示输出。
watch
命令示例!
基本上没有 您只能使用--progress标志显示每个文件的进度,仅此而已。
我猜您可以围绕它编写包装程序,也可以使用已经找到的任何补丁,但是您必须问自己是否真的值得,您是否真的需要rsync的全部进步?
--progress
工作方式--info=progress2
,它将向您显示全局进度。您将需要禁用增量递归算法才能使它有用,所以--info=progress2 --no-inc-recursive
我使用了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的总进度,并从这篇文章中找到了有用的答案:https ://stackoverflow.com/questions/7157973/monitoring-rsync-progress
基本上,您可以在rsync 3.1.0的开发版本中使用--info = progress2。这是医生说的:
还有一个--info = progress2选项,它基于整个传输而不是单个文件输出统计信息。使用此标志而不输出文件名(例如,避免使用-v或指定--info = name0,如果您希望在不滚动具有很多名称的屏幕的情况下查看传输的情况。(您无需指定-进度选项以使用--info = progress2。)
--info=name0
是金🌈👑–
我使用了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)
它发现文件数量非常快!
find
仅当您在rsync
本地-ing 时才有效。rsync --dry-run
也适用于远程源...
采用
lsof -ad3-999 -c rsync
要查看rsync当前打开了哪些文件(将显示文件大小),rsync将复制到本地隐藏文件中
for i in $(pgrep 'rsync'); do ls -l /proc/$i/fd; done
但是您的解决方案更简单。
我会发表评论,但没有足够的声誉。为响应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.
请注意这里的警告,即使--info = progress2也不是完全可靠的,因为这是基于进度显示时rsync“知道”的文件数的百分比。这不一定是需要同步的文件总数(例如,如果它在深度嵌套的目录中发现大量大文件)。确保--info = progress2在进度指示中不“跳回”的一种方法是强制rsync在开始同步之前以递归方式扫描所有目录(而不是执行增量递归扫描的默认行为),通过提供--no-inc-recursive选项。但是请注意,此选项还将增加rsync内存使用率和运行时间。
--no-inc-recursive
选项或其较短的--no-i-r
别名来禁用增量递归。(查看其他答案)
我使用了一个脚本,该脚本从/ 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 -------------------------------------------------------------------"
在这里可能会有点晚,但是将来的求职者可能会受益。
这也困扰着我,所以我想我会变得肮脏不堪,写我的第一个脚本。必须安装zenity软件包(sudo apt-get install zenity),但我确定它可能已经存在。另外,我使用wmctrl(窗口管理器控件)在完成时更改进度对话框的标题,它易于安装,但如果没有的话,不会有所作为。我只想在面板中查看完成的时间。
该脚本主要要求提供源目录和目标目录,并使用du计算目标在源中占源的百分比,并显示进度条。
注意:这仅适用于完整的目录/文件同步(我通常使用它来备份apt缓存),因此没有--exclude = / file / in / Source-directory选项。如果目标目录中没有源目录中的文件/目录,也将不起作用。我不确定它是否适用于远程源/目的地,因为从来没有我需要它或资源来对其进行测试。
PS。该脚本可能写得很差或效率很低(此处为纯脚本),但至少可以达到目的,当然,欢迎您对其进行编辑和改进以适合您的需求。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