alp*_*293 8 shell-script hashsum gnu-parallel
我有一个文件夹,里面有大量我想要计算 SHA256 哈希的文件。
我曾经对代码段进行编码:
#!/bin/bash
for file in *; do
sha256sum "$file" > "$file".sha &
done
Run Code Online (Sandbox Code Playgroud)
目前并行计算 sha256 哈希,除了我的计算机只有 16 个物理内核。
所以,我的问题是如何使用 GNU 并行运行它,但只使用我系统上可用的 16 个物理内核运行,并且一旦完成哈希,它会自动选择下一个文件散列?
使用xargs
(并假设您有一个支持-0
和 的实用程序的实现-P
):
printf '%s\0' * | xargs -0 -L 1 -P 16 sh -c 'sha256sum "$1" > "$1".sha' sh
Run Code Online (Sandbox Code Playgroud)
这会将当前目录中的所有名称作为以空字符结尾的列表传递给xargs
. 该xargs
实用程序将为sh
这些名称中的每一个调用一个内嵌脚本,从最多 16 个并发进程开始。内嵌脚本接受参数并sha256sum
在其上运行,将结果输出到具有相似名称的文件中。
请注意,这也可能会拾取.sha
在同一管道的先前运行中创建的文件。为避免这种情况,请使用稍微复杂的 glob,而不是*
匹配您要处理的特定名称。例如,在bash
:
shopt -s extglob
printf '%s\0' !(*.sha) | xargs ...as above...
Run Code Online (Sandbox Code Playgroud)
另请注意sha256sum
,并行运行大型文件可能受磁盘限制而不是 CPU 限制,并且您可能会看到类似的操作速度与较少数量的并行任务。
对于 GNUparallel
等效项,请替换xargs
为parallel
.
在zsh
shell中,你可以这样做
printf '%s\0' * | xargs -0 -L 1 -P 16 sh -c 'sha256sum "$1" > "$1".sha' sh
Run Code Online (Sandbox Code Playgroud)
使用 GNU parallel
,您可以完全避免 shell 循环,只需运行:
parallel -P 16 sha256sum {} ">"{}.sha ::: *
Run Code Online (Sandbox Code Playgroud)
这将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
Run Code Online (Sandbox Code Playgroud)
但是,请记住@Kusalandanda指出的这类事情的主要瓶颈是 I/O 而不一定是 CPU。您可能希望并行运行少于 16 个。