繁体   English   中英

通过脚本(Bash)执行时模块未加载

[英]Modules not loading when executed via a script (Bash)

我正在编写一个 bash 脚本来对文件执行一些命令。 为此,我需要加载包含这些命令的模块。 现在我可以从命令行执行这些操作就好了,但是我想在脚本中执行检查以查看这些模块是否已加载,如果未加载,则加载它们。 这是我到目前为止所做的(我只有 3 天时间学习 bash,所以请原谅任何新手错误):

#A list with all the necessary modules
declare -a modules=("CDO/1.9.7-gompi-2019a" "ncview/2.1.7-gompi-2019a")

echo "Running script"
echo ""

#Check if modules are loaded. If not, load them
for mod in "${modules[@]}"
do
    module is-loaded $mod

    if [ $? = 1 ]
    then
        echo "Loading ${mod}"
        module load $mod
    else
        echo "${mod} is already loaded"
    fi
done

echo ""
echo "Finished running script"

它进入 if 语句,表示该模块未加载,然后说“正在加载 CDO...”,但是当我尝试使用来自该模块的命令时,它不起作用,因为该模块似乎没有被执行. 但是“模块已加载”执行得很好。 我究竟做错了什么?

[diyon@login2 scripts]$ ./script.sh
Running script

Loading CDO/1.9.7-gompi-2019a
Loading ncview/2.1.7-gompi-2019a

Finished running script
[diyon@login2 scripts]$ cdo
-bash: cdo: command not found

线索在全名中:“Environment Modules”

这些模块(不要与内核模块或任何其他模块混淆)是用于配置当前环境(用于开发环境、管理员等)的工具。

直到今天我才听说过这些。 根据这些幻灯片,他们使用包含用 Tcl 编写的声明性环境描述的模块文件。 加载它们时,它们会转换为 shell 语法,并在当前环境中进行eval

—————————

您的脚本不起作用的原因是 shell 脚本在新进程中执行,并且无法更改其父进程的环境 - 您从中启动它的 shell。 您配置了脚本的环境(模块相关命令将在其中工作),但是当脚本退出时该环境消失了

解决方案可能是在模块文件( man modulefilehttps://linux.die.net/man/4/modulefile )或“模块”文档推荐的任何文件中配置您的环境模块。

或者,您可以将脚本实现为shell 函数 Shell 函数在当前 Shell 环境中执行,因此您的模块仍将在它结束时加载。

如果您运行type module ,您可以看到该module本身是一个 shell 函数,这就是它能够修改当前环境的原因。

如果将以下函数附加到文件~/.bashrc并重新启动 shell,则可以运行load_modules来执行它。

我认为在这种情况下不需要引用(变量等),但我还是添加了它。

load_modules ()
{
    # A list with all the necessary modules
    local -a modules=('CDO/1.9.7-gompi-2019a'
                      'ncview/2.1.7-gompi-2019a')
    local mod

    echo "Running function"
    echo

    # Check if modules are loaded. If not, load them
    for mod in "${modules[@]}"
    do
        if module is-loaded "$mod"
        then
            echo "$mod is already loaded"
        else
            echo "Loading $mod…"
            module load "$mod"
        fi
    done

    echo
    echo "Finished running the function"
}

来自Environment Modules软件的module命令更新当前环境会话。

正如@dan 所解释的那样,当作为./script.sh执行时,您的脚本在子shell 中运行,该子shell 在脚本执行结束时结束。 因此,当以这种方式运行时,脚本会更新子 shell 的 shell 环境而不是父 shell。

如果您在当前 shell 会话中使用source script.sh脚本,您将在当前 shell(而不是在 subshel​​l 会话中)执行module load命令,因此您将以更新当前 shell 环境结束。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM