我如何在我的Bash脚本中使用并行编程/多线程?

12
这是我的脚本:
#!/bin/bash
#script to loop through directories to merge fastq files
sourcedir=/path/to/source
destdir=/path/to/dest

for f in $sourcedir/*
do
    fbase=$(basename "$f")
    echo "Inside $fbase"
    zcat $f/*R1*.fastq.gz | gzip > $destdir/"$fbase"_R1.fastq.gz
    zcat $f/*R2*.fastq.gz | gzip > $destdir/"$fbase"_R2.fastq.gz
done

这里有大约30个子目录在目录“source”中。每个子目录都有特定的R1.fastq.gz文件和R2.fastq.gz文件,我想将它们合并成一个R1.fastq.gz和R2.fastq.gz文件,然后保存到目标目录中。我的代码工作得很好,但由于数据量的原因,我需要加快速度。我想知道是否有办法在我的脚本中实现多线程编程?如何运行我的脚本,以便多个作业并行运行?由于对Bash脚本不熟悉,所以任何帮助将不胜感激。


既然你明显在处理生物信息学,那么你应该阅读这些内容:http://www.biostars.org/p/81359/ 和 http://www.biostars.org/p/63816/。 - Ole Tange
2个回答

9

最简单的方法是在命令的末尾添加&,将命令放在后台执行:

#!/bin/bash
#script to loop through directories to merge fastq files
sourcedir=/path/to/source
destdir=/path/to/dest

for f in $sourcedir/*
do
    fbase=$(basename "$f")
    echo "Inside $fbase"
    zcat $f/*R1*.fastq.gz | gzip > $destdir/"$fbase"_R1.fastq.gz &
    zcat $f/*R2*.fastq.gz | gzip > $destdir/"$fbase"_R2.fastq.gz &
done

根据 bash 手册
如果一个命令以控制运算符“&”结束,则 shell 在子 shell 中异步执行该命令。这被称为在后台执行命令。shell 不等待命令完成,返回状态为 0(真)。当作业控制未激活(参见作业控制),异步命令的标准输入,在没有任何显式重定向的情况下,会从 /dev/null 重定向。

1
@user2703967 是的...添加 & 会生成一个新的子shell,它只是在执行自己的任务,而您的脚本则继续运行。如果您需要比这更复杂的东西,那么您可能首先不应该使用bash。 - Zero Piraeus
谢谢,最后一个问题。当我在“完成”之后使用“等待”,这有什么区别? - Komal Rathi
@user2703967 它会等待后台作业完成,然后继续执行。对于您的示例脚本,在那一点上脚本已经完成,这没有任何区别 - 如果您想要处理后台作业的结果,您将需要它。 - Zero Piraeus
1
@user2703967 只需让您的操作系统处理它(它会自动处理)。除非您正在进行过于复杂以至于无法在bash中考虑的操作,否则这真的不是一个问题。 - Zero Piraeus
2
这太聪明了,而且显而易见!哇,非常感谢。 - Robert Beltran
显示剩余2条评论

3

我不确定,但你可以试着在命令的结尾处使用&,就像这样:

zcat $f/*R1*.fastq.gz | gzip > $destdir/"$fbase"_R1.fastq.gz &
zcat $f/*R2*.fastq.gz | gzip > $destdir/"$fbase"_R2.fastq.gz &

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接