使用 GNU parallel 并行化 bash for 循环
Use GNU parallel to parallelise a bash for loop
我有一个 for 循环,它 运行 是一个 Python 脚本,在 100 个不同的输入文件夹上执行了大约 100 次。 python 脚本在 2 个内核上效率最高,我有 50 个内核可用。因此,我想一次在 25 个文件夹上使用与 运行 脚本并行的 GNU。
这是我的 for 循环(工作正常,但当然是顺序的),python 脚本接受一堆输入变量,包括 -p 2
,运行 它在两个核心数:
for folder in $(find /home/rob/PartitionFinder/ -maxdepth 2 -type d); do
python script.py --raxml --quick --no-ml-tree $folder --force -p 2
done
这是我对其进行并行化的尝试,但没有成功:
folders=$(find /home/rob/PartitionFinder/ -maxdepth 2 -type d)
echo $folders | parallel -P 25 python script.py --raxml --quick --no-ml-tree {} --force -p 2
我遇到的问题(也许这只是众多问题中的第一个)是我的 folders
变量不是列表,所以它实际上只是传递一长串 100 个文件夹作为 {}
到脚本。
感谢收到所有提示。
你可以直接通过管道查找并行:
find /home/rob/PartitionFinder/ -maxdepth 2 -type d | parallel -P 25 python script.py --raxml --quick --no-ml-tree {} --force -p 2
如果您想将字符串保留在 $folder
中,您可以将回显通过管道传递给 xargs。
echo $folders | xargs -n 1 | parallel -P 25 python script.py --raxml --quick --no-ml-tree {} --force -p 2
将echo $folders | parallel ...
替换为echo "$folders" | parallel ...
。
没有双引号,shell 解析 $folders
中的空格并将它们作为单独的参数传递给 echo
,这导致它们打印在一行上。 parallel
提供每一行作为作业的参数。
为了完全避免此类引用问题,最好将 find
直接通过管道传递给 parallel
,并使用空字符作为分隔符:
find ... -print0 | parallel -0 ...
即使遇到包含多个空格或换行符的文件名,这也会起作用。
您可以这样创建 Makefile
:
#!/usr/bin/make -f
FOLDERS=$(shell find /home/rob/PartitionFinder/ -maxdepth 2 -type d)
all: ${FOLDERS}
# To execute the find before the all
find_folders:
@ echo $(FOLDERS) > /dev/null
${FOLDERS}: find_folders
@ python script.py --raxml --quick --no-ml-tree $@ --force -p 2
然后是运行make -j 25
注意:在文件中使用制表符缩进
此外,名称中包含空格的文件将不起作用。
我有一个 for 循环,它 运行 是一个 Python 脚本,在 100 个不同的输入文件夹上执行了大约 100 次。 python 脚本在 2 个内核上效率最高,我有 50 个内核可用。因此,我想一次在 25 个文件夹上使用与 运行 脚本并行的 GNU。
这是我的 for 循环(工作正常,但当然是顺序的),python 脚本接受一堆输入变量,包括 -p 2
,运行 它在两个核心数:
for folder in $(find /home/rob/PartitionFinder/ -maxdepth 2 -type d); do
python script.py --raxml --quick --no-ml-tree $folder --force -p 2
done
这是我对其进行并行化的尝试,但没有成功:
folders=$(find /home/rob/PartitionFinder/ -maxdepth 2 -type d)
echo $folders | parallel -P 25 python script.py --raxml --quick --no-ml-tree {} --force -p 2
我遇到的问题(也许这只是众多问题中的第一个)是我的 folders
变量不是列表,所以它实际上只是传递一长串 100 个文件夹作为 {}
到脚本。
感谢收到所有提示。
你可以直接通过管道查找并行:
find /home/rob/PartitionFinder/ -maxdepth 2 -type d | parallel -P 25 python script.py --raxml --quick --no-ml-tree {} --force -p 2
如果您想将字符串保留在 $folder
中,您可以将回显通过管道传递给 xargs。
echo $folders | xargs -n 1 | parallel -P 25 python script.py --raxml --quick --no-ml-tree {} --force -p 2
将echo $folders | parallel ...
替换为echo "$folders" | parallel ...
。
没有双引号,shell 解析 $folders
中的空格并将它们作为单独的参数传递给 echo
,这导致它们打印在一行上。 parallel
提供每一行作为作业的参数。
为了完全避免此类引用问题,最好将 find
直接通过管道传递给 parallel
,并使用空字符作为分隔符:
find ... -print0 | parallel -0 ...
即使遇到包含多个空格或换行符的文件名,这也会起作用。
您可以这样创建 Makefile
:
#!/usr/bin/make -f
FOLDERS=$(shell find /home/rob/PartitionFinder/ -maxdepth 2 -type d)
all: ${FOLDERS}
# To execute the find before the all
find_folders:
@ echo $(FOLDERS) > /dev/null
${FOLDERS}: find_folders
@ python script.py --raxml --quick --no-ml-tree $@ --force -p 2
然后是运行make -j 25
注意:在文件中使用制表符缩进
此外,名称中包含空格的文件将不起作用。