1

我想创建一个小脚本来在集群上显示 slurm 输出而无需等待。它几乎可以工作,只是我必须在另一个 shell 的同一文件夹中执行 ls (或其他磁盘访问)才能启动显示。我不明白为什么。这是脚本:

#!/bin/bash

set -o errexit
set -o pipefail
set -o nounset

LOG=$(sbatch $1 | awk '{print $4}')
i=1
declare -a progress=("/" "-" "\\" "-")
while [ ! -f res_${LOG}.log ]; do
    /bin/echo -n -e "Waiting for res_${LOG}.log to appear ${progress[$((${i} % 4))]} \r"
    i=$((${i}+1))
    sleep 1
done
echo
tail -f res_${LOG}.log

请注意,它使用给定的命令启动sbatch,然后反复检查是否出现了 slurm 日志文件,这意味着作业已启动。不幸的是,如果我不在另一个 shell 或脚本中进行文件系统访问,while 循环永远不会退出。如果我添加

ls >& /dev/null

就在 之后sleep 1,一旦出现日志文件,循环就会按预期退出。

下面的最小示例有问题。调用wait.slurm,我用./sbatch.sh wait.slurm.

#!/bin/bash
 
#SBATCH --output=res_%j.log
 
while [ 1 ]; 
        do echo hello;
        sleep 1;
done

我怀疑文件系统级别有一些奇怪的事情,但我想了解它是什么。

4

1 回答 1

0

我假设这是在网络文件系统(例如 NFS)上。有几种机制可以在这里发挥作用:

  • 提交节点上的文件系统客户端可以有一个缓存机制,通过将信息保存在本地内存中并每分钟左右更新一次,可以更快地查询文件系统;
  • 计算节点上的文件系统客户端可以有一个缓冲机制,其中写入被分组到更大的写入操作集合中,以避免许多小写入,有利于更少的较大写入,从而使操作更快;
  • 文件系统服务器可以配置为也具有缓冲区和缓存。

运行该ls命令似乎会强制文件系统同步其操作(刷新缓冲区、无效缓存)。

您可以尝试sync从计算节点调用系统调用。例如在你的例子中

#!/bin/bash
 
#SBATCH --output=res_%j.log
 
while [ 1 ]; 
        do echo hello;
        sync
        sleep 1;
done

如果安装了inotifywait命令,更好的方法可能是使用它。

于 2021-03-09T13:08:26.800 回答