[英]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 modulefile
或https://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(而不是在 subshell 會話中)執行module load
命令,因此您將以更新當前 shell 環境結束。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.