我正在按原样运行以下 bash 脚本。即依次进行。请注意, 和prefetch
是fastq-dump
从数据库下载文件的调用,并且_shrink
是我为缩小获取的文件而编写的 C++ 程序(由于存储空间有限)。
我可以使用线程来实现这个功能吗?下载文件需要很长时间。
重要的!每个块内的命令必须顺序运行,但允许块并行运行。此外,我想一次只运行 10 个块。
#!/bin/bash
g++ -std=c++11 shrink_files.cpp -o _shrink
#block1
prefetch SRR837459
fastq-dump --fasta 0 SRR837459
rm ../../sra_sequences/sra/SRR837459.sra
./_shrink SRR837459
rm SRR837459.fasta
echo "SRR837459" >> list_of_done.txt
#block1
prefetch SRR805782
fastq-dump --fasta 0 SRR805782
rm ../../sra_sequences/sra/SRR805782.sra
./_shrink SRR805782
rm SRR805782.fasta
echo "SRR805782" >> list_of_done.txt
#... more blocks
答案1
我认为并行命令的一个好方法可能是......GNUparallel
。将您的块定义为函数格伦·杰克曼建议然后并行运行它们,其中-j
允许定义最大并行运行。相对于 Glenn 的方法的优点是,如果完成了任何一个块,就会启动一个新的块,因此您总是同时运行 10 个块。请注意,您必须导出并行函数才能看到它。
#!/bin/bash
g++ -std=c++11 shrink_files.cpp -o _shrink
block() {
prefetch "$1"
fastq-dump --fasta 0 "$1"
...
}
export -f block
parallel -j 10 block ::: id1 id2 id3 id4 ....
替换idi
为您的 id。或者,如果您在类似文件中拥有 ID(SRR837459 等)
id1
id2
id3
然后使用这一行(如果没有其他输入源,GNU Parallel 从标准输入读取):
parallel -j 10 block
并通过运行脚本
bash script < idlist.txt
答案2
您可以对命令进行分组以在后台运行
未经测试的
#!/bin/bash
g++ -std=c++11 shrink_files.cpp -o _shrink
block() {
local id=$1
prefetch "$id"
fastq-dump --fasta 0 "$id"
rm ../../sra_sequences/sra/"$id".sra
./_shrink "$id"
rm "$id".fasta
echo "$id" >> list_of_done.txt
}
# run first 10 blocks in the background
block SRR837459 &
block SRR805782 &
...
block 10th_id &
# and wait for them to complete
wait
# now start up on the next 10 ...
block 11th_id &
...
或者下面的代码更具编程性:
# all the ids to fetch
ids=( SRR837459 SRR805782 ... )
while (( ${#ids[@]} > 0 )); do
# copy the first 10 as positional parameters
set -- "${ids[@]:0:10}"
# launch the blocks
for id; do
block "$id" &
done
# wait until done
wait
# remove the first 10 from the list
ids=( "${ids[@]:10}" )
done