如何在执行rsync备份前预计算备份数据的总大小?
如何在执行rsync备份前预计算备份数据的总大小?
我明白你遇到的问题了——当目录里文件数量特别多的时候,把所有路径一次性传给du会触发Argument list too long的错误,而用xargs分批处理时如果没正确累加结果,也会得到不准确的数值。这里有几个靠谱的解决方法,按推荐程度排序:
方法一:用rsync自带的统计功能(最省心高效)
其实rsync本身就可以在模拟备份时输出要传输的数据总大小,根本不需要额外调用du。只需要加上--stats参数,就能直接拿到准确的统计结果:
rsync -avn --exclude=你的排除规则 --delete --stats "$source" "$target" | grep "Total file size"
解释:
-n是模拟运行,不会实际修改文件;--stats会让rsync输出详细的备份统计信息,其中Total file size这一行就是所有需要传输的文件的总大小;- 这个方法完全避开了处理大量文件路径的问题,既高效又准确,是首选方案。
方法二:用循环逐个累加文件大小(解决参数过长问题)
如果你还是想用du来计算,可以用while循环逐个处理每个文件/目录的路径,避免一次性把所有路径传给du:
total_size=0 # 先通过rsync模拟得到需要备份的文件/目录路径 rsync -avn --exclude=你的排除规则 --delete "$source" "$target" | \ grep -E '^[^/]+/' | grep -v " bytes/sec" | grep -v "deleting " | \ cut -d "/" -f2- | awk 'NF' | \ while read -r relative_path; do # 计算单个路径的大小,累加总和 dir_size=$(du -s -- "$source/$relative_path" 2>/dev/null | awk '{print $1}') total_size=$((total_size + dir_size)) done # 转换为易读的GB单位(也可以换成MB、KB) echo "总备份大小:$((total_size / 1024 / 1024)) GB"
解释:
- 用
while read逐个读取路径,避免了参数列表过长的问题; - 每次只给
du传一个路径,累加所有结果得到总大小; 2>/dev/null用来忽略du可能出现的权限不足等错误。
方法三:修复你的xargs命令(正确累加结果)
你之前用xargs的问题在于,tail -1只取了最后一批du输出的大小,而没有累加所有批次的结果。可以用awk来累加所有du的输出:
rsync -avn --exclude=你的排除规则 --delete "$source" "$target" | \ grep / | grep -v " bytes/sec" | grep -v "deleting " | \ cut -d "/" -f2- | awk 'NF' | \ awk -v src="$source" '{print src"/"$0}' | \ xargs du -s -- 2>/dev/null | \ awk '{sum += $1} END {print sum / 1024 / 1024 " GB"}'
解释:
- 最后用
awk '{sum += $1} END {print sum ...}'累加所有du输出的第一列(大小数值),得到总大小; -v src="$source"用来把环境变量source传给awk,避免硬编码路径。
备注:内容来源于stack exchange,提问作者rumpel
相关产品推荐
相关产品推荐

