如何获取用于 SLURM 作业的脚本的原始位置?

问题描述 投票:0回答:4

我正在使用脚本启动 SLURM 作业,并且脚本必须根据其位置来工作,该位置是通过

SCRIPT_LOCATION=$(realpath $0)
在脚本本身内部获取的。但是 SLURM 将脚本复制到
slurmd
文件夹并从那里开始工作,这会搞砸进一步的操作。

是否有任何选项可以在移动/复制之前获取用于 slurm 作业的脚本的位置?

脚本位于网络共享文件夹

/storage/software_folder/software_name/scripts/this_script.sh
并且它必须:

  1. 获取自己的位置
  2. 返回
    software_name
    文件夹
  3. software_name
    文件夹复制到节点上的本地文件夹
    /node_folder
  4. 从复制的文件夹运行另一个脚本
    /node_folder/software_name/scripts/launch.sh

我的剧本是

#!/bin/bash
#SBATCH --nodes=1
#SBATCH --partition=my_partition_name

# getting location of software_name 
SHARED_PATH=$(dirname $(dirname $(realpath $0)))
# separating the software_name from path
SOFTWARE_NAME=$(basename $SHARED_PATH)
# target location to copy project
LOCAL_SOFTWARE_FOLDER='/node_folder'
# corrected path for target
LOCAL_PATH=$LOCAL_SOFTWARE_FOLDER/$SOFTWARE_NAME

# Copying software folder from network storage to local
cp -r $SHARED_PATH $LOCAL_SOFTWARE_FOLDER
# running the script
sh $LOCAL_PATH/scripts/launch.sh

当我通过以下方式在节点本身上运行它(不使用 SLURM)时,它运行完美:

sh /storage/software/scripts/this_script.sh

如果使用 SLURM 运行它

sbatch /storage/software/scripts/this_script.sh
它被分配给其中一个节点,但是:

  • 在运行之前,它被复制到
    /var/spool/slurmd/job_number/slurm_script
    ,并且由于
    $(dirname $(dirname $(realpath $0)))
    返回
    /var/spool/slurmd
  • ,所以一切都搞砸了

当使用SLURM启动脚本时,是否可以获取脚本内部的原始位置(

/storage/software_folder/software_name/
)?

附注所有机器都运行 Fedora 30 (x64)

更新1

有人建议以

sbatch -D /storage/software_folder/software_name ./scripts/this_script.sh
运行并在脚本本身内部使用
SHARED_PATH="${SLURM_SUBMIT_DIR}"
。 但它会引发错误
sbatch: error: Unable to open file ./scripts/this_script.sh

另外,我尝试使用绝对路径:

sbatch -D /storage/software_folder/software_name /storage/software_folder/software_name/scripts/this_script.sh
。它尝试运行,但是:

  • 在这种情况下,它仅使用指定的文件夹来创建输出文件
  • 软件仍然不想运行
  • 尝试在脚本打印中使用
    echo "${SLURM_SUBMIT_DIR}"
    /home/username_who_started_script
    而不是
    /storage/software_folder/software_name

还有其他建议吗?

更新2: 还尝试在脚本内部使用

#SBATCH --chdir=/storage/software_folder/software_name
,但在这种情况下
echo "${SLURM_SUBMIT_DIR}"
返回
/home/username_who_started_script
/
(如果以 root 身份运行)

更新3

使用

${SLURM_SUBMIT_DIR}
的方法仅在任务运行时有效:

cd /storage/software_folder/software_name
sbatch ./scripts/this_script.sh

但这似乎不是一个合适的解决方案。还有其他方法吗?

解决方案

#!/bin/bash
#SBATCH --nodes=1
#SBATCH --partition=my_partition_name

# check if script is started via SLURM or bash
# if with SLURM: there variable '$SLURM_JOB_ID' will exist
# `if [ -n $SLURM_JOB_ID ]` checks if $SLURM_JOB_ID is not an empty string
if [ -n $SLURM_JOB_ID ];  then
    # check the original location through scontrol and $SLURM_JOB_ID
    SCRIPT_PATH=$(scontrol show job $SLURM_JOBID | awk -F= '/Command=/{print $2}')
else
    # otherwise: started with bash. Get the real location.
    SCRIPT_PATH=$(realpath $0)
fi

# getting location of software_name 
SHARED_PATH=$(dirname $(dirname $(SCRIPT_PATH)))
# separating the software_name from path
SOFTWARE_NAME=$(basename $SHARED_PATH)
# target location to copy project
LOCAL_SOFTWARE_FOLDER='/node_folder'
# corrected path for target
LOCAL_PATH=$LOCAL_SOFTWARE_FOLDER/$SOFTWARE_NAME

# Copying software folder from network storage to local
cp -r $SHARED_PATH $LOCAL_SOFTWARE_FOLDER
# running the script
sh $LOCAL_PATH/scripts/launch.sh
bash variables path slurm
4个回答
14
投票

您可以从

scontrol
获取提交脚本的初始(即提交时)位置,如下所示:

scontrol show job "$SLURM_JOB_ID" | awk -F= '/Command=/{print $2}'

所以你可以用上面的内容替换

realpath $0
部分。当然,这只适用于 Slurm 分配。因此,如果您希望脚本在任何情况下都能工作,您将需要一些逻辑,例如:

if [ -n "${SLURM_JOB_ID:-}" ] ; then
THEPATH=$(scontrol show job "$SLURM_JOB_ID" | awk -F= '/Command=/{print $2}')
else
THEPATH=$(realpath "$0")
fi

然后继续

SHARED_PATH=$(dirname "$(dirname "${THEPATH}")")

1
投票

我必须在数组作业中执行相同的操作,@damienfrancois接受的答案适用于除与 ArrayJobId 相同的 jobid 之外的所有作业。只需将 awk 命令通过管道传输到 head 命令即可解决问题

scontrol show job $SLURM_JOBID | awk -F= '/Command=/{print $2}' | head -n 1

0
投票

在脚本中,将

SHARED_PATH
设为
SHARED_PATH="${SLURM_SUBMIT_DIR}"

将脚本提交为

sbatch -D /storage/software ./scripts/this_script.sh

请参阅此处

来自参考页面:

-D

将批处理脚本的工作目录设置为其之前的目录 被执行。路径可以指定为完整路径或相对路径 到执行命令的目录。

SLURM_SUBMIT_DIR

调用 sbatch 的目录,或者,如果适用,由 -D、--chdir 选项指定的目录。

P.S. 以上来自版本 19.05 文档。
在查看存档时,参考Ver. 18.x(尤其是18.08),它没有提到相同的内容。参见这个

SLURM_SUBMIT_DIR

调用 sbatch 的目录。


0
投票

如果使用 SLURM 如果采用返回参数的第一条路径,则

#SBATCH --array Job Array 
@damienfrancois 有效。 @Karthik Govindappa的回复对我不起作用,但这种方法https://unix.stackexchange.com/a/53315导致

IFS=' ' read -r THEPATH string <<< $(scontrol show job "$SLURM_JOB_ID" | awk -F= '/Command=/{print $2}')
© www.soinside.com 2019 - 2024. All rights reserved.