如何让SLURM作业查询离#SBATCH --time指定时长结束的剩余运行时间
如何在SLURM作业中查询剩余运行时长?
你完全可以不用手动传递作业ID或写文件,SLURM本身提供了更简洁的解决方案:
核心:利用SLURM内置环境变量获取作业ID
作业运行时,SLURM会自动为每个任务设置SLURM_JOB_ID环境变量,直接在脚本里引用即可,无需额外操作。
方法1:用squeue精准提取时间字段
避免依赖输出列索引(容易因SLURM版本/配置变化失效),用--format指定只输出需要的字段:
# 获取作业总分配时长(格式如 1-00:00:00 或 02:30:00) total_time=$(squeue -j "$SLURM_JOB_ID" --format="%L" -h) # 获取已运行时长(格式如 00:15:42) elapsed_time=$(squeue -j "$SLURM_JOB_ID" --format="%M" -h)
方法2:用sacct获取更可靠的作业时间数据
sacct是SLURM专门用于查询作业记账信息的工具,输出更稳定:
# 提取总时长(Timelimit)和已运行时长(Elapsed),-P用|分隔字段,-n去掉表头 sacct_output=$(sacct -j "$SLURM_JOB_ID" --format=Timelimit,Elapsed --state=RUNNING -n -P) # 分割字段赋值 IFS='|' read -r total_time elapsed_time <<< "$sacct_output"
计算剩余时长的脚本示例
把时间字符串转成秒计算差值,再转回易读格式:
# 时间字符串转秒数 time_to_seconds() { local time_str=$1 local days=0 hours=0 minutes=0 seconds=0 if [[ $time_str =~ ^([0-9]+)-([0-9]+):([0-9]+):([0-9]+)$ ]]; then days=${BASH_REMATCH[1]} hours=${BASH_REMATCH[2]} minutes=${BASH_REMATCH[3]} seconds=${BASH_REMATCH[4]} elif [[ $time_str =~ ^([0-9]+):([0-9]+):([0-9]+)$ ]]; then hours=${BASH_REMATCH[1]} minutes=${BASH_REMATCH[2]} seconds=${BASH_REMATCH[3]} elif [[ $time_str =~ ^([0-9]+):([0-9]+)$ ]]; then minutes=${BASH_REMATCH[1]} seconds=${BASH_REMATCH[2]} fi echo $(( days*86400 + hours*3600 + minutes*60 + seconds )) } # 秒数转回易读时间格式 seconds_to_time() { local sec=$1 local days=$(( sec / 86400 )) sec=$(( sec % 86400 )) local hours=$(( sec / 3600 )) sec=$(( sec % 3600 )) local minutes=$(( sec / 60 )) sec=$(( sec % 60 )) if [ $days -gt 0 ]; then echo "${days}-${hours}:${minutes}:${sec}" else echo "${hours}:${minutes}:${sec}" fi } # 计算并输出剩余时长 total_sec=$(time_to_seconds "$total_time") elapsed_sec=$(time_to_seconds "$elapsed_time") remaining_sec=$(( total_sec - elapsed_sec )) remaining_time=$(seconds_to_time "$remaining_sec") echo "当前作业剩余运行时长:$remaining_time"
为什么这个方案更优?
- 无需手动管理作业ID:
SLURM_JOB_ID由系统自动注入,完全避免多作业冲突 - 输出字段可控:用
--format指定字段,不会因squeue输出列变化导致脚本失效 - 数据更可靠:
sacct直接读取SLURM的记账数据库,比squeue的实时状态输出更稳定
内容的提问来源于stack exchange,提问作者GRquanti
相关产品推荐
相关产品推荐

