Slurm作业脚本中能否在SBATCH预定义段前设置变量?
Slurm脚本中SBATCH指令前设置变量的可行性及替代方案
你的示例方法不可行,原因是:Slurm在提交作业时会优先扫描并解析脚本中的#SBATCH指令,这个阶段脚本还未被bash执行,因此你在#SBATCH前定义的NODE_NUM变量不会被解析,输出文件名里的${NODE_NUM}会原样保留,无法得到预期的节点编号值。
以下是两种可行的替代方案:
方案一:动态生成Slurm脚本
先在父脚本中计算变量值,再将变量代入生成新的Slurm脚本,最后提交这个生成的脚本。示例代码:
#!/bin/bash # 在父脚本中计算变量 NODE_NUM=$(echo -n $HOSTNAME | tail -c 1) # 生成包含变量值的Slurm脚本 cat > temp_job.sh << EOF #!/bin/bash #SBATCH --output=logs/job_notebook_${NODE_NUM}.out # 这里填写作业执行的实际命令 srun your_task_command EOF # 提交生成的作业脚本 sbatch temp_job.sh
方案二:提交命令行传递变量/参数
直接在sbatch命令行中指定输出文件名(或传递变量),命令行参数的优先级高于脚本内的#SBATCH指令。示例:
# 先计算变量 NODE_NUM=$(echo -n $HOSTNAME | tail -c 1) # 提交时指定输出文件 sbatch --output=logs/job_notebook_${NODE_NUM}.out your_original_script.sh
此时原脚本中的#SBATCH --output可以删除,或者保留但会被命令行参数覆盖。
额外说明:如果需要基于执行节点而非提交节点设置文件名
如果你的需求是根据作业实际运行的节点来命名输出文件(而非提交作业的节点),上面两种方法都不适用(因为$HOSTNAME是提交节点的主机名)。此时可以用Slurm内置的环境变量或输出占位符:
- 使用Slurm输出占位符:
#SBATCH --output=logs/job_notebook_%N.out
其中%N会自动替换为作业执行节点的主机名。
2. 脚本执行阶段重定向输出:
#!/bin/bash #SBATCH --output=logs/job_notebook_temp.out # 作业启动后获取执行节点的编号 NODE_NUM=$(echo -n $SLURMD_NODENAME | tail -c 1) # 重命名临时输出文件 mv logs/job_notebook_temp.out logs/job_notebook_${NODE_NUM}.out # 执行作业命令 srun your_task_command
内容的提问来源于stack exchange,提问作者GuyMatz
相关产品推荐
相关产品推荐

