如何从其他Shell脚本获取Slurm批量作业的退出码?
嘿,这个场景我太熟悉了——批量提交Slurm作业做自动化流程,想要追踪每个作业的退出码确实是个核心需求。给你分享几个我日常用的靠谱方法,按需选就行:
方法1:用sacct查询作业官方记录
这是Slurm原生的最通用方法,sacct可以读取集群的作业记账系统,直接获取退出码信息。步骤很简单:
- 提交作业时捕获作业ID,存起来
- 等待作业完成(可选,如果你需要同步处理的话)
- 用
sacct查询该作业的退出码
示例脚本:
# 提交单个作业并捕获ID JOB_ID=$(sbatch my_job_script.sh | awk '{print $4}') # 等待作业完成(循环检查squeue,直到作业不在队列中) echo "等待作业 $JOB_ID 完成..." while squeue -j $JOB_ID > /dev/null 2>&1; do sleep 10 # 每10秒检查一次 done # 查询退出码,注意ExitCode的格式是「<脚本退出码>:<终止信号>」 EXIT_CODE=$(sacct -j $JOB_ID --format=ExitCode --noheader | awk '{print $1}' | head -n1) echo "作业 $JOB_ID 的退出码:$EXIT_CODE"
小提示:如果是正常退出,终止信号部分会是0;如果作业被信号终止(比如OOM killed),后面会显示对应的信号编号(比如137对应SIGKILL)。
方法2:让作业自己把退出码写入文件
如果你的集群限制了sacct的访问权限,或者你想绕开Slurm的记账系统,这个方法更直接:在作业脚本的末尾,把自身的退出码写入一个共享存储的文件里。
首先修改你的作业脚本my_job_script.sh:
# 你的作业逻辑... echo "作业执行中..." # 这里写你的任务命令 # 最后把退出码写入文件,用SLURM_JOB_ID作为文件名后缀确保唯一 echo $? > /shared/storage/job_exit_${SLURM_JOB_ID}.txt
然后在提交脚本里,等待作业完成后读取这个文件:
JOB_ID=$(sbatch my_job_script.sh | awk '{print $4}') # 等待作业完成 while squeue -j $JOB_ID > /dev/null 2>&1; do sleep 10 done # 读取退出码 EXIT_CODE=$(cat /shared/storage/job_exit_${JOB_ID}.txt) echo "作业 $JOB_ID 的退出码:$EXIT_CODE"
注意:一定要用集群的共享存储路径(比如NFS挂载的目录),不然计算节点写入的文件你在提交节点读不到。
方法3:批量作业的退出码批量追踪
如果是一次性提交十几个甚至上百个作业,你可以把所有作业ID存进数组,然后批量等待、批量查询:
# 批量提交作业,收集所有作业ID JOB_IDS=() for task_num in {1..10}; do # 提交带任务编号的作业 job_id=$(sbatch --job-name=batch_task_${task_num} my_job_script.sh | awk '{print $4}') JOB_IDS+=($job_id) echo "提交作业 $job_id" done # 等待所有作业完成 echo "等待所有作业结束..." while true; do # 检查队列中是否还有我们的作业(squeue表头占1行,所以行数<=1表示没有作业了) running_count=$(squeue -j ${JOB_IDS[*]} 2>/dev/null | wc -l) if [ $running_count -le 1 ]; then break fi sleep 30 # 批量作业可以拉长检查间隔,减少集群压力 done # 逐个查询退出码 echo "所有作业完成,退出码如下:" for job_id in "${JOB_IDS[@]}"; do exit_code=$(sacct -j $job_id --format=ExitCode --noheader | awk '{print $1}' | head -n1) echo "- 作业 $job_id:$exit_code" done
一些额外提醒
- 如果是Slurm数组作业(用
--array提交),sacct会返回每个数组任务的退出码,你可以用--format=JobID,ExitCode来区分每个子任务 - 有些集群的
sacct可能有延迟,作业刚结束时查不到结果,可以多等几秒再查询 - 如果你不需要同步等待,也可以后台运行监控脚本,定时检查作业状态并记录退出码
内容的提问来源于stack exchange,提问作者JimBamFeng




