Я запускаю задание SLURM с помощью сценария, и сценарий должен работать в зависимости от его местоположения, которое получается внутри самого сценария с помощью SCRIPT_LOCATION=$(realpath $0)
. Но SLURM копирует скрипт в папку slurmd
и запускает задание оттуда, и это приводит к дальнейшим ошибкам.
Есть ли какая-либо опция, позволяющая получить местоположение сценария, используемого для задания грязи, до его перемещения / копирования?
Скрипт находится в общей сетевой папке /storage/software_folder/software_name/scripts/this_script.sh
и должен:
- получить свое собственное местоположение
- вернуть папку
software_name
- скопировать папку
software_name
в локальную папку /node_folder
на узле
- запустить другой скрипт из скопированной папки
/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
Можно ли получить исходное местоположение (/storage/software_folder/software_name/
) внутри скрипта, когда он запускается с SLURM?
P.S. Все машины работают на 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