我有一个文件夹,其中有大量文件,我想为其计算 SHA256 哈希值。
我曾经编码段:
#!/bin/bash
for file in *; do
sha256sum "$file" > "$file".sha &
done
目前正在并行计算 sha256 哈希,只不过我的计算机只有 16 个物理核心。
所以,我的问题是如何使用 GNU 并行来运行它,但仅使用我系统上可用的 16 个物理核心运行,并且一旦完成哈希,它将自动拾取下一个文件哈希?
答案1
使用 GNU parallel
,您可以完全避免 shell 循环,只需运行:
parallel -P 16 sha256sum {} ">"{}.sha ::: *
这将sha256sum
在 glob 返回的每个文件(或目录,但这就是您的脚本所做的)上运行*
,并将输出保存在fileName.sha
.例如:
$ ls
file1 file2 file3 file4 file5
$ parallel -P 16 sha256sum {} ">"{}.sha ::: *
$ ls
file1 file2 file3 file4 file5
file1.sha file2.sha file3.sha file4.sha file5.sha
但是,请记住@Kusalandanda指出这类事情的主要瓶颈是 I/O 而不一定是 CPU。您可能希望并行运行少于 16 个。
答案2
使用(并假设您有支持和 的xargs
该实用程序的实现):-0
-P
printf '%s\0' * | xargs -0 -L 1 -P 16 sh -c 'sha256sum "$1" > "$1".sha' sh
这会将当前目录中的所有名称作为以 null 结尾的列表传递到xargs
.该xargs
实用程序将为这些名称中的每一个调用一个内联sh
脚本,最多启动 16 个并发进程。内联脚本接受参数并sha256sum
对其运行,将结果输出到具有相似名称的文件中。
请注意,这也可能会拾取.sha
在同一管道的先前运行中创建的文件。为了避免这种情况,请使用比*
您要处理的特定名称更复杂的 glob 。例如,在bash
:
shopt -s extglob
printf '%s\0' !(*.sha) | xargs ...as above...
另请注意,并行运行sha256sum
大文件可能会受到磁盘限制,而不是 CPU 限制,并且您可能会看到与较少数量的并行任务类似的操作速度。
对于 GNUparallel
等效项,请替换xargs
为parallel
.
在zsh
shell 中,你可以这样做
autoload -U zargs
setopt EXTENDED_GLOB
zargs -P 16 -L 1 -- (^(*.sha)) -- sh -c 'sha256sum "$1" > "$1".sha' sh