计算 rsync 备份的大小

问题描述 投票:0回答:1

我试图在执行 rsync 备份之前计算它的大小:

du -hs -- $(rsync -avn --exclude --delete $source $target | grep / | grep -v " bytes/sec" | grep -v "deleting " | cut -d "/" -f2- |  awk 'NF' | awk '$0="$source/"$0')

它失败并出现错误:参数列表太长。 据我了解,该命令大于 ARG_MAX 限制。

我也尝试过 xargs,但也失败了:

rsync -avn --exclude --delete $source $target | grep / | grep -v " bytes/sec" | grep -v "deleting " | cut -d "/" -f2- |  awk 'NF' | awk '$0="$source/"$0'| xargs -P4 -n9999999  du  -hs -- 2>/dev/null | tail -1 | awk {'print $1'}

(最终输出23GB,但远不止于此)

我的问题是:是否有另一种方法来预先计算 rsync 备份的大小?

谢谢

bash rsync xargs du
1个回答
0
投票

xargs
“失败”的原因是你丢弃了它的一些输出。

回顾一下,当你得到“参数列表太长”时,这意味着你的参数比内核常量大

ARG_MAX

xargs
通过多次运行相同的命令来解决这个问题。例如,如果
echo one two three four
太长,并且您将其与
xargs
分开,那么您将有效地运行

echo one two
echo three four

您会注意到,虽然原始输出是一行,但此重新表述会产生两行。使用

xargs
时,您需要认识到这样的事情。

回到您的示例,您需要接受

du
将运行多次,并采取额外的步骤将它们重新收集在一起。您已经在使用 Awk;所以只需编写一个更好的 Awk 脚本即可。

rsync -avn --exclude --delete "$source" "$target" |
awk -v s="$source" '   /bytes\/sec|deleting/ { next }
  /\// { sub(/^[^/]*\//, s "/", $0) print } ' |
xargs -P4 du -ks -- 2>/dev/null |
awk '{ sum =+ $1 }
  END { print sum / 1024*1024*1024 }'

还请注意,我们不想使用

du -h
,因为这样我们就无法预测它将使用什么输出单位。
xargs
最终可能会在最后一次调用中在单个小文件上运行它,然后您将获得以字节、千字节或兆字节为单位的输出,而不是使用
du -h
时的千兆字节输出。我们用 Awk 计算总数,然后然后以千兆字节为单位进行格式化。

(你可以想象一下,而不是硬编码千兆字节,但我将把它作为练习。)

我还将您复杂的

grep | cut / | awk
重构为一个 Awk 脚本,尽管无法访问数据,但很难确定它是否正确。我相信我修复了一个错误,您可能想在输出中添加 shell 变量
source
的值,而不是静态文本
$source
。请记住,shell 和 Awk 是两种不同的语言,并且无法访问彼此的变量。

最后,引用你的变量,并且当你显然不知道可以挤入多少个参数时,不要在

-n
中硬编码一个大的
xargs
值;无论如何,它都会默认为最大可能的数字。

© www.soinside.com 2019 - 2024. All rights reserved.