完成shell脚本根据输入自动生成0-n数字命名文件夹,文件夹包含输出文件夹路径的shell脚本。编写slurm脚本,调用shell脚本,实现批量提交,输出自动生成文件夹绝对路径
用sbatch提交作业首先要申请资源,申请多少资源(节点数,输入输出等等)需要进行说明,有两种说明方法(以提交的shell脚本为task.sh为例,提交前建议给该文件777权限):
个人目前使用情况(未在shell脚本中说明, 使用1个节点32个核,gjf计算文件/vasp计算文件夹内执行):
(gaussian 16 : sbatch -c32 -pTH_LONG3N g16.sh)
(VASP : sbatch -N 1 -n 32 -p TH_LONG3N vasp.sh)
(1) 不在脚本中声明,在在终端中进行声明,如:
①shell脚本的内容如下:
#!/bin/bash
#<1.source 环境变量>
# 天河二号和非sbatch提交的脚本会自动source ~/.bashrc,因此此步可以忽略
# 本地计算机使用sbatch命令提交shell脚本,由于是在由于是在nonloginshell环境里运行,而非interactive loginshell,并不会自动source ~/.bashrc 的环境变量,因此有两种解决方案
解决方案1: 此处加上source ~/.bashrc
解决方案2: 此处按顺序export 和source所有所需的变量。
# <2.执行运行软件>
# 高斯执行方式1(gjf文件同目录下直接执行): g16 < test.gjf > test.out
# 高斯执行方式2(同目录下,srun): srun -c 32 -p TH_LONG3N g16 < test.gjf > test.out
# VASP执行方式1(文件夹内, srun,老超算): srun -p TH_NEW1 -N 1 -n 12 vasp软件路径
# VASP执行方式2(文件夹内, srun,新超算): srun -p LONG_3N -N 1 -n 32 vasp软件路径
②终端提交命令如下:
cd task.sh的文件路径 #mobaxterm可以中键锁定路径,不用手动输入了
sbatch -p TH_LONG3N -N 1 -n 1 -c 32 task.sh #也可以winscp打开文件所在位置,shift+ctrl+T, 然后输入命令。这样可以不需要cd命令。
(2) 在shell脚本文件开头进行声明,在终端直接提交:
注释行并非没用, 第一行#!是说明用什么语言,比如bash语言,删了就不能正常运行。
#SBATCH其实是能正常读取的。具体说明见北大超算sbatch 常用参数。2
#!/bin/bash
#SBATCH -p TH_LONG3N #可以用sinfo查看分区,老超算为TH_NEW1,新超算为TH_LONG3N,超算中debug3N分区不用参与大循环,但是运行时间上线为半小时。
#SBATCH -N 1 #使用1个节点
#SBATCH -n 1 #1个进程
#SBATCH -c 32 #每个任务所需要的核心数为32个核(clusters)。老超算则为12个核
#<1.source 环境变量>
# 天河二号和非sbatch提交的脚本会自动source ~/.bashrc,因此此步可以忽略
# 本地计算机使用sbatch命令提交shell脚本,由于是在由于是在nonloginshell环境里运行,而非interactive loginshell,并不会自动source ~/.bashrc 的环境变量,因此有两种解决方案
解决方案1: 此处加上 source ~/.bashrc
解决方案2: 此处按顺序 export 和 source 所有所需的变量。
# <2.执行运行软件>
# 高斯执行方式1(gjf文件同目录下直接执行): g16 < test.gjf > test.out
# 高斯执行方式2(同目录下,srun): srun -c 32 -p TH_LONG3N g16 < test.gjf > test.out
# VASP执行方式1(文件夹内, srun,老超算): srun -p TH_NEW1 -N 1 -n 12 vasp软件路径
# VASP执行方式2(文件夹内, srun,新超算): srun -p LONG_3N -N 1 -n 32 vasp软件路径
②终端提交命令如下:
cd task.sh的文件路径 #mobaxterm可以中键锁定路径,不用手动输入了
sbatch task.sh #因为已经在sh文件中声明了,所以此处就不需要-N -n了
补充: 如果想要多个程序并行执行,需要在程序运行命令后面加上&
符号(运行该命令后继续执行脚本,而等待程序运行完再进入下一步),并且再sh脚本最后加上wait
命令,即等待所有程序运行结束后脚本才停止。否则会因脚本的直接停止关掉程序。
你参考下,是不是你想要的
#!/bin/bash
# 获取输入参数
n=$1
# 创建目录
mkdir -p "$n"
# 生成脚本文件
cat <<EOF > "$n/output.sh"
#!/bin/bash
# 输出当前目录路径
echo "\$(pwd)"
EOF
# 授予脚本执行权限
chmod +x "$n/output.sh"
# 提交脚本到Slurm集群
sbatch "$n/output.sh"
#!/bin/bash
# 获取输入参数
n=$1
# 循环提交作业
for i in {0..n}
do
# 创建目录
mkdir -p "$i"
# 生成脚本文件
cat <<EOF > "$i/output.sh"
#!/bin/bash
# 输出当前目录路径
echo "\$(pwd)"
EOF
# 授予脚本执行权限
chmod +x "$i/output.sh"
# 提交脚本到Slurm集群
sbatch "$i/output.sh"
done
先编写一个 shell 脚本,根据输入生成 0-n 数字命名的文件夹,并包含输出文件夹路径:
#!/bin/bash
# 获取输入的数字范围
min=$1
max=$2
# 创建输出文件夹路径
output_dir="$PWD/output"
if [ ! -d "$output_dir" ]; then
mkdir "$output_dir"
fi
# 循环创建文件夹
for i in $(seq "$min" "$max"); do
folder_name="folder$i"
folder_path="$output_dir/$folder_name"
if [ ! -d "$folder_path" ]; then
mkdir "$folder_path"
fi
done
# 输出生成的文件夹绝对路径
output_folders=("$output_dir/folder$min" "$output_dir/folder$((min+1))" "$output_dir/folder$max")
for folder in "${output_folders[@]}"; do
echo "$folder"
done
之后再编写一个 slurm 脚本,调用 create_folders.sh 脚本并批量提交
#!/bin/bash
input_number=$1
output_folder=$2
for i in {0..$input_number}
do
folder_name=$i
mkdir $folder_name
echo "output_folder=\"$output_folder/$folder_name/\"" > $folder_name/script.sh
done
#!/bin/bash
input_number=$1
output_folder=$2
for i in {0..$input_number}
do
folder_name=$i
job_script=$folder_name/script.sh
output_folder=$output_folder/$folder_name/
sbatch << EOF
#!/bin/bash -l
#SBATCH --job-name=job-$folder_name
#SBATCH --output=job-%j.out
#SBATCH --error=job-%j.err
#SBATCH --ntasks=1
#SBATCH --mem-per-cpu=1000
bash $job_script
EOF
done
参考如下:
#!/bin/bash
# 获取输入参数
n=$1
# 创建输出文件夹
for ((i=0; i<=n; i++))
do
folder_name="folder_$i"
mkdir $folder_name
# 创建包含输出文件夹路径的shell脚本
echo "#!/bin/bash" > $folder_name/output_script.sh
echo "output_folder=\$(cd \$(dirname \$0); pwd)" >> $folder_name/output_script.sh
chmod +x $folder_name/output_script.sh
done
保存以上脚本为generate_folders.sh
。
编写一个slurm脚本,调用上述shell脚本并实现批量提交任务。假设我们要生成10个文件夹,可以使用以下示例:
#!/bin/bash
#SBATCH --job-name=generate_folders
#SBATCH --output=generate_folders_%j.out
#SBATCH --error=generate_folders_%j.err
# 调用shell脚本生成文件夹和输出脚本
srun bash generate_folders.sh 10
# 输出自动生成的文件夹绝对路径
for ((i=0; i<=10; i++))
do
folder_name="folder_$i"
output_folder=$(cat $folder_name/output_script.sh | grep "output_folder" | awk -F'=' '{print $2}')
echo "Folder $i: $output_folder"
done
保存以上脚本为submit_slurm.sh
。
最后,在终端中使用以下命令提交slurm任务:
sbatch submit_slurm.sh
shell脚本:
#!/bin/bash
n=$1
for ((i=0; i<=n; i++))
do
folder_name="folder_$i"
mkdir $folder_name
# 创建输出路径的脚本文件
echo "#!/bin/bash" > $folder_name/run.sh
echo "echo \"当前文件夹的绝对路径:\$(pwd)\"" >> $folder_name/run.sh
done
效果:
#!/bin/bash
#SBATCH --job-name=generate_folders
#SBATCH --output=generate_folders_%j.out
#SBATCH --error=generate_folders_%j.err
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=1
#SBATCH --time=00:01:00
# 调用shell脚本生成文件夹和脚本文件,假设n=5
./script.sh 5
shell脚本示例
#!/bin/bash
echo "请输入一个整数 n:"
read n
for ((i=0; i<=n; i++))
do
folder_name="folder_$i"
mkdir $folder_name
echo "#!/bin/bash" > ${folder_name}/output.sh
echo "echo '输出文件夹路径: $(pwd)/$folder_name'" >> ${folder_name}/output.sh
chmod +x ${folder_name}/output.sh
done