使用GNU parallel来并行化bash for循环

时间:2017-06-05 11:01:31

标签: python unix gnu-parallel

我有一个for循环,在100个不同的输入文件夹上运行Python脚本~100次。 python脚本在2个内核上最有效,我有50个内核可用。所以我想使用GNU parallel一次在25个文件夹上运行脚本。

这里是我的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个文件夹的字符串。

感谢所有提示。

3 个答案:

答案 0 :(得分:5)

echo $folders | parallel ...替换为echo "$folders" | parallel ...

如果没有双引号,shell会解析$folders中的空格,并将它们作为单独的参数传递给echo,这会导致它们打印在一行上。 parallel将每一行作为作业的参数。

为了完全避免这样的引用问题,最好直接将find传递给parallel,并使用空字符作为分隔符:

find ... -print0 | parallel -0 ...

即使遇到包含多个空格或换行符的文件名,这也会起作用。

答案 1 :(得分:2)

你可以直接找到并行管道:

 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

答案 2 :(得分: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

小心:使用标签缩进文件

此外,名称中包含空格的文件也无法使用。