在脚本中为rsync实现进度输出的bash命令

3
这个脚本是Linux Live-CD安装程序的一部分。
rsync -aq / /TARGET/ exclude-from=exclude.list &>> errors.log

我希望能够向GUI报告进度。GUI(gtkdialog)对任意数字0-100做出响应(例如,echo 1; echo 2;等等...)。

在这种情况下,rsync -n(干运行)需要太长时间。

我希望运行...

filesystem_size=`(get directory size) / exclude=exclude.list`
rsync -aq / /TARGET/ exclude-from=exclude.list &
while [ rsync is running ]; do
    (check size) /TARGET/
    compare to $filesystem_size
    echo $number (based on the difference of sizes)
done

请帮忙获取目录大小并排除多个文件,同时在rsync运行时使用while循环,根据两个大小的差异输出数字(0-100)。回答以上任何问题都是很大的帮助,谢谢。
编辑:添加完成的rsync进度输出(似乎有足够多的人需要这个) 在Olivier Dulac的帮助下,我做到了这一点。
size_source=`du -bs --exclude-from=/path/to/exclude.list /source/ | sed "s/[^0-9]*//g"`

size_target=`du -bs /target/ | sed "s/[^0-9]*//g"`

rsync -aq /source/ /target/ --exclude-from=/path/to/exclude.list &

while [[ `jobs | grep "rsync"` ]]; do
  size_target_new=`du -bs /TARGET/ | sed "s/[^0-9]*//g"`
  size_progress=`expr $size_target_new - $size_target`
  expr 100 \* $size_progress / $size_source
  sleep 10
done

此命令将在命令行上打印出%的进度,仅适用于大文件传输。
如果rsync覆盖文件,则会使进度显示不准确(显示的进度比实际完成的要少)。
在rsync和du中,exclude.list的读取方式相同。但是,du始终需要完整路径,而rsync则假定exclude文件位于其源内。如果复制根文件系统“/”,则它们可以是同一个文件。否则,您必须为du编写完整的路径(只需将每行文件开头添加/source/即可)。

你不能只是使用选项 --progress 吗? - Olivier Dulac
1
rsync --progress 每个文件输出进度,而不是总体。 - user2225483
1个回答

3

为确定目标和源(带排除项)的总大小:

filesystem_size=$(find /SOURCE -ls | fgrep -f exclude.list  -v | awk '{ TOTAL += $6} END { print int ( TOTAL / 1024 ) }')
     # the above considers you only have, in exclude.list, a list of /path/ or /path/to/files 
     # with no spaces on those files or path. If it contains patterns, change "fgrep" with "egrep". 
     # And give us examples of those patterns so we can adjust the egrep.
     # It also consider that "find ... -ls" will print the size in the 6th column.
size_target=$(du -ks /TARGET | awk '{print $1}')
#there are other ways: 
#   if /TARGET is on different filesystem than /SOURCE, 
#   and if reasonnably sure nothing else is writing on the /TARGET filesystem : 
#     you can use "df -k /TARGET | awk '{print $n}' (n= column showing the size in k)
#     to monitor the target progress.
#     But you need to take its size before starting the rsync, 
#     and then compare it with the current size

循环语句:

while  jobs | grep 'sync' ; do ... ; done
    #It is probably wise to add in the loop a "sleep 5" or something to avoid doing too many size computations, too often.

对于尺寸:

echo "100 * $size_target / $filesystem_size" | bc

请告诉我这些是否适用于你。如果不适用,请提供尽可能多的细节以帮助确定你的需求。


2
文件系统大小=$(find / -ls | fgrep -f /tmp/exclude.list -v | awk '{ TOTAL += $6} END { print TOTAL /1024 }')rsync -aq / /TARGET/ --exclude-from=/tmp/exclude.list &while jobs | grep "sync"; do size_target=$(du -ks /TARGET | awk '{print $1}') if [ ! $size_target ]; then size_target="1"; fi expr 100 \* $size_target / $filesystem_size sleep 5 done#expr: 非整数参数 echo $filesystem_size = 624.165除了一些小问题,您已经很好地解决了我的问题 :) - user2225483
@user2225483 很高兴能帮到你 :). 对于 awk 语句中的非整数参数表示抱歉:我现在已经用 "int( ... )" 进行了更正,以强制结果为整数。 - Olivier Dulac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接