簡體   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