如何调整bash脚本使unicycler.sh与prokka.sh通过qsub按序执行?
我通常分别执行以下两个bash脚本:
for i in `cat sample_id.txt`;do qsub unicycler.sh ${i};done for i in `cat sample_id.text`do qsub prokka.sh ${i};done为了让它们按序执行,我编写了新脚本
ass_ann.sh:#!/bin/bash TEXT_ID=sampleid.txt for i in `cat path/to/file/${TEXT_ID};do qsub unicycler.sh ${i};done && for i in `cat path/to/file/${TEXT_ID};do qsub prokka.sh ${i};done我以为用
&&可让命令按序执行,但unicycler.sh能正常运行,prokka.sh却报错assembly.fasta' is not a readable non-empty FASTA file,这说明prokka.sh在unicycler.sh生成文件前就启动了。请告诉我如何调整脚本让两个任务都成功执行?
核心问题:
qsub是把任务提交到集群调度系统(比如PBS),而非本地直接执行。你原来的&&只是等待所有unicycler任务提交完成,就立刻提交prokka任务,但此时集群上的unicycler任务可能还在运行,根本没生成assembly.fasta文件。方法1:给每个prokka任务添加依赖,等待对应样本的unicycler任务完成
修改脚本,捕获每个unicycler任务的Job ID,然后提交prokka时指定依赖该Job ID:#!/bin/bash TEXT_ID=sampleid.txt while IFS= read -r i; do # 提交unicycler任务并捕获Job ID unicycler_job=$(qsub unicycler.sh "${i}") # 提取纯Job ID(有些qsub会输出类似"12345.server",需要截取数字部分) unicycler_job_id=$(echo "$unicycler_job" | awk '{print $1}') # 提交prokka任务,指定依赖unicycler任务成功完成 qsub -W depend=afterok:"${unicycler_job_id}" prokka.sh "${i}" done < path/to/file/"${TEXT_ID}"注:
-W depend=afterok:jobid表示只有当指定的jobid任务成功退出(返回码0)后,才会启动当前prokka任务。如果允许unicycler失败后仍执行prokka,可以用afterany代替afterok。方法2:先批量提交所有unicycler任务,再统一提交依赖所有unicycler的prokka任务(适合所有样本完成后再批量注释的场景)
#!/bin/bash TEXT_ID=sampleid.txt # 存储所有unicycler的Job ID job_ids=() while IFS= read -r i; do job=$(qsub unicycler.sh "${i}") job_ids+=("$(echo "$job" | awk '{print $1}')") done < path/to/file/"${TEXT_ID}" # 将Job ID用逗号拼接,作为prokka任务的依赖 depend_str=$(IFS=,; echo "${job_ids[*]}") # 提交所有prokka任务,等待所有unicycler完成 while IFS= read -r i; do qsub -W depend=afterok:"${depend_str}" prokka.sh "${i}" done < path/to/file/"${TEXT_ID}"方法3:将单个样本的unicycler和prokka合并为一个脚本,提交单个任务
创建single_sample_pipeline.sh:#!/bin/bash #$ -N sample_pipeline # 任务名,PBS集群请改用#PBS -N # 按需添加其他集群参数(比如内存、队列) sample_id="$1" # 先执行unicycler ./unicycler.sh "$sample_id" # 再执行prokka ./prokka.sh "$sample_id"然后提交所有样本的任务:
for i in `cat sample_id.txt`; do qsub single_sample_pipeline.sh "${i}"; done这种方式确保单个样本的两个步骤在同一个任务里顺序执行,无需依赖调度系统的依赖设置。
内容的提问来源于stack exchange,提问作者Ana

