有没有办法使用 xargs 或并行进行并行复制但保持文件夹结构?

有没有办法使用 xargs 或并行进行并行复制但保持文件夹结构?

我尝试在 bash 中实现并行复制以增加吞吐量。

find <src> -type f -print0 | shuf -z | xargs -0 -P8 -n50 cp --parents  -t <dest>

上述命令不起作用,因为存在竞争,即某些父目录已被其他 cp 进程创建。我想知道是否有办法传递类似的东西--exists-ok,让 cp 命令忽略现有的父目录。

或者也许有其他现有工具可以做到这一点?

所有已回答的问题^1^ 其他地方无法处理--parents这个意思,它们只适用于单目录级别的文件。

有几个实际上不起作用的替代方案:

查找所有目录而不是所有文件,然后先 mkdir 并cp *在目录中进行操作。这种方法解决了错误。但它错过了增加复制吞吐量的要点。因为有些目录的文件比其他目录多得多:

find $src -type d -links 2 -print0 | shuf -z | xargs -0 -P8 -I{} bash -c "mkdir {}; cp -R {} $dest/"

如果 1 或 2 目录有很多文件,那么我最终会运行 1 或 2 个进程很长时间。

当然,我可以再次在每个目录中派生更多副本。但是,这会增加进程数,并且当许多目录仅包含少量文件时,我最终会生成大量 cp 进程。这也会减慢速度。

无法做到

我再三考虑,这根本行不通。这并不是因为 cp 无法忽略现有目录,另一个工具 cpio 可以做到这一点。但是,每个进程都在争相创建目录。当两个进程都看到根本没有目录时,它们可以开始创建相同的父目录。因此,目录创建需要在单个线程中完成,然后才能将所有文件写入该目录。

答案1

您面临着目录创建和文件复制之间的竞争条件。

我在简单的备份脚本中所做的是:

  • 首先创建所有目录,这通常很快就能完成
  • 然后开始复制。由于所有目录都已创建,因此不再存在竞争条件。

相关内容