长复制期间“du”命令的输出是什么?

长复制期间“du”命令的输出是什么?

最近,我启动了cp创建大目录备份的命令。所以,我使用了这样的命令:

cp -rv big_directory new_location

因为文件很大,所以执行这个命令花了很长时间,我也想看看复制的进度。所以我还在du另一个终端中使用了该命令,如下所示:

du -sh new_location/*

但这个命令执行起来也需要很长时间。特别是如果该目录中有大文件。

假设cp执行该命令需要 10 分钟。如果我du在启动命令 1 分钟后启动该cp命令,并假设du需要 1 分钟才能执行,我想知道我是否可以信任du?的输出

它是否为我提供了启动时 (t=1min) 情况的可靠输出du,或者是否为我提供了执行时间结束时du(t=2min) 情况的输出?显然,由于复制,目录的大小在命令new_location开始和结束之间发生了变化。du

答案1

@derobert 解释了如何du运作。

他没有提到,除非您有绝对大量的小文件/目录(因此元数据需要大量内存),否则du立即再次运行通常会更快地产生结果。

一个大文件并不会使du速度变慢,但复制它更有可能将目录缓存挤出内存。 (桌面响应能力可以提高通过设置vm.swappiness=10,并使用 sysctl 设置将元数据优先于数据vm.vfs_cache_pressure=60(将它们放入/etc/sysctl.d/99-local.)

当多个进程同时访问文件系统时,每个系统调用都会获取运行时状态快照的信息。例如,进程可能会检查文件是否存在,然后尝试打开它,却发现它不再存在。因为在检查之间的时间间隔内另一个进程已重命名/删除了它。 (当这导致问题/是错误的根源时,称为竞争条件。)

如果 的目录遍历顺序du与选择的顺序相同cp,则du直到运行时接近结束时才会到达仍在修改的目录,因此不会错过太多时间结束了。 OTOH,如果首先对放置新文件du的目录求和cp,然后再花一分钟对其余的求和,结果将是陈旧的。

答案2

du通过递归扫描目录来工作,计算所有文件和目录的大小。就像是:

  1. 从命令行上给出的第一个目录开始。
  2. stat目录以确定其大小,并将其添加到总数中
  3. 从目录中读取第一个条目(文件或子目录名称)
  4. 如果它是一个文件,stat则将其添加到总数中
  5. 如果它是一个目录(当然不是...),则对子目录执行步骤 2-7
  6. 如果还有另一个条目,请阅读它并返回到 4 [您可能想知道:如果在扫描单个目录cp时添加另一个条目会发生什么?du标准说它可能会或可能不会出现——未指定。]
  7. 打印出目录大小

如果目录和文件像du所有这些一样发生变化(就像您的情况一样),那么它给出的大小不是从头到尾的大小,而是介于两者之间的大小 - 但不完全是。不过可能已经足够接近了,至少对于cp.

要获取进度指示器,除了 @roaima 的rsync建议之外,还有cp -v, gcp(通过快速搜索找到)和复杂的东西,例如(cd /src && tar c .) | pv -pterb -s $(du -sb /src) | (cd /dst && tar x).

答案3

如果您已经rsync安装,您可以像这样查看复制进度

rsync -vP big_directory new_location

如果您想保留权限、时间戳、所有权等,您可以将标志添加-arsync或 将-p标志添加到cp


这个答案回避了使用 的du假设,即您实际上想观察复制的进度,而不是查看所用磁盘空间的近似值。

相关内容