srun随身更换

时间:2019-01-16 12:56:35

标签: bash slurm

我正在尝试创建一个函数来代替SLURM的srun命令。这个包装函数的需要是,我希望在SLURM控制下启动时使用srun编写脚本,但是仍然能够在没有SLURM的情况下运行脚本。

到目前为止,我具有此功能:

srun_wrap() {
    if [ -z "$SLURM_JOB_ID" ]
    then
        # Not running under SLURM so start the code without srun
        "${@:2}"
    else
        # A SLURM job ID found, so use srun
        srun ${@:1:1} "${@:2}"
    fi
}

这使我可以像这样变换一行

srun --job-name listing ls

到一行

srun_wrapper "--job-name listing" ls

非常接近插件,但还没有。

原因是:

  • 检查变量$SLURM_JOB_ID的值
    • 如果变量中没有值,则意味着我们不在SLURM之下,并且应在不运行srun的情况下运行命令。大括号扩展会忽略第一个参数(srun参数),并运行其余命令行。
    • 如果有值,则表示我们处于SLURM分配中,因此请使用srun。命令行由srun(第一个参数未加引号)组成,以允许srun正确地识别参数,最后是真实的命令行已被正确加引号。

这种方法仍然有两个缺点:

  1. 括号扩展中的srun参数必须不带引号,否则不要 由srun正确解析。
  2. 进行呼叫时,srun参数必须用引号引起来,以被视为单个参数。
  3. 我被迫总是将参数传递给包装器,即使是空的。 srun ls将转换为srun_wrapper "" ls

关于如何克服这三个缺点的任何想法?如何引用括号扩展,如何避免引用srun参数以及如何避免需要空参数?

1 个答案:

答案 0 :(得分:0)

这是我想出的。 Shell向导可能会做得更好。这样可以解决您所有的缺点吗?

这确实有我正在研究的新缺点。标志不能有空格。因此,您必须像这样使用它们:srun_wrap --ntasks=2 lssrun_wrap -n2 ls

echo的调用和最后的函数调用仅用于调试。

#!/bin/bash

function srun_wrap {
        i=1
        for var in "$@"; do
                # args starting with '-' up to the first that doesn't are srun
                # flags. The rest of the args are the command
                if [[ $var == -* ]]; then
                        flags=( "${flags[@]}" "$var" )
                else
                        cmd="${@:$i}"
                        break
                fi
                i=$((i+1))
        done
        echo "flags = $flags"
        echo "cmd = $cmd"

        if [ "x$SLURM_JOB_ID" != "x" ]; then
                # run in slurm
                eval "srun ${flags[@]} ${cmd[@]}"
        else
                # run outside slurm
                eval "${cmd[@]}"
        fi
}

srun_wrap "$@"

要解决标志问题,您可以自己定义一个标志(如--cmd之类的),以将srun标志与可执行文件分开。

srun_wrap --ntasks 2 --exclusive --cmd ls -alh

或者您可以像sbatch这样更明确地创建自己解析的--wrap=<command>标志。不过,您必须引用它。

srun_wrap --ntasks 2 --exclusive --wrap="ls -alh"

唯一的另一种选择是自己创建一个选项解析器,以检测有效的运行标志。那将是很多工作,并且可能会产生错误。