如何为Slurm数组添加例外:仅在全部任务完成后执行单次命令
Slurm数组任务完成后仅执行一次删除命令的解决方案
给你两种可行的方案,能把删除命令整合到同一个脚本里,避免每个数组任务都执行删除:
方案一:嵌套提交依赖清理任务(推荐)
思路是让脚本自己判断运行状态:如果是首次执行(不是数组任务),就先提交整个数组任务,再提交一个依赖于数组全部成功完成的清理任务;如果是数组任务,就执行原本的处理逻辑。
修改后的完整脚本:
#!/bin/bash # 数组任务的Slurm配置(只有用sbatch提交时才生效) #SBATCH -A XXX-CPU #SBATCH --mail-type=BEGIN,END,FAIL #SBATCH -p cclake #SBATCH -D analyses/ #SBATCH -c 12 #SBATCH -t 01:00:00 #SBATCH --mem=10G #SBATCH -J splitBAM #SBATCH -a 1-12 #SBATCH -o analyses/splitBAM_%a.log # 如果当前是数组任务,执行原有处理逻辑 if [ -n "$SLURM_ARRAY_TASK_ID" ]; then sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands1.csv | bash sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands2.csv | bash sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands3.csv | bash else # 首次执行脚本,提交数组任务并获取Job ID ARRAY_JOB_ID=$(sbatch --parsable "$0") echo "数组任务已提交,Job ID: $ARRAY_JOB_ID" # 提交依赖于数组全部成功完成的清理任务 sbatch --dependency=afterok:$ARRAY_JOB_ID \ -A XXX-CPU \ -p cclake \ -D analyses/ \ -c 1 \ -t 00:05:00 \ --mem=1G \ -J cleanup_splitBAM \ -o analyses/cleanup_splitBAM.log \ << 'EOF' #!/bin/bash rm file1 file2 file3 EOF fi
使用方式:直接在终端运行这个脚本(不用加sbatch),它会自动提交数组任务和后续的清理任务。清理任务会在所有数组任务成功完成后才执行。
方案二:用任务标记文件触发清理
思路是每个数组任务完成后创建一个标记文件,最后由某个任务检查所有标记文件是否存在,只有全部存在时才执行删除。注意:这种方法依赖文件系统一致性,适合简单场景,可靠性不如方案一。
修改后的脚本:
#!/bin/bash #SBATCH -A XXX-CPU #SBATCH --mail-type=BEGIN,END,FAIL #SBATCH -p cclake #SBATCH -D analyses/ #SBATCH -c 12 #SBATCH -t 01:00:00 #SBATCH --mem=10G #SBATCH -J splitBAM #SBATCH -a 1-12 #SBATCH -o analyses/splitBAM_%a.log # 执行原有数组任务逻辑 sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands1.csv | bash sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands2.csv | bash sed -n ${SLURM_ARRAY_TASK_ID}p analyses/slurm/commands3.csv | bash # 创建当前任务完成的标记文件 touch ".task_${SLURM_ARRAY_TASK_ID}_done" # 检查所有任务的标记文件是否都存在 TOTAL_TASKS=12 ALL_FINISHED=1 for i in $(seq 1 $TOTAL_TASKS); do if [ ! -f ".task_${i}_done" ]; then ALL_FINISHED=0 break fi done # 如果所有任务都完成,执行删除并清理标记文件 if [ $ALL_FINISHED -eq 1 ]; then rm file1 file2 file3 rm .task_*.done fi
使用方式:直接用sbatch提交这个脚本即可。如果某个数组任务失败,对应的标记文件不会创建,删除操作就不会执行,符合你原本依赖afterok的需求。
内容的提问来源于stack exchange,提问作者justinian482
相关产品推荐
相关产品推荐

