You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何从其他Shell脚本获取Slurm批量作业的退出码?

嘿,这个场景我太熟悉了——批量提交Slurm作业做自动化流程,想要追踪每个作业的退出码确实是个核心需求。给你分享几个我日常用的靠谱方法,按需选就行:

方法1:用sacct查询作业官方记录

这是Slurm原生的最通用方法,sacct可以读取集群的作业记账系统,直接获取退出码信息。步骤很简单:

  1. 提交作业时捕获作业ID,存起来
  2. 等待作业完成(可选,如果你需要同步处理的话)
  3. 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

火山引擎 最新活动