我使用大量计算群集,并且这些群集通常使用模块系统来制作可用的软件包。基本上,您使用模块命令(例如module load sample_software
),将sample_software
路径添加到$PATH
中。在群集上,可以在交互式使用和提交提交用法中调用此命令。
我安装了一个带有PBS/Torque排队系统的Linux盒,以便我可以沙盒软件以供以后在簇上使用。我需要一个非常相似的模块系统。我首先在我的`/etc/profile.d/目录中制作一个名为 modules.sh
的文件,该文件看起来像这样:
module()
{
if [ $2 == "softwareX" ]; then
PATH=$PATH:/home/me/dir/softwareX
export PATH
fi
}
然后,我将以下行放在我的.bash_profile
脚本中:
source /etc/profile.d/modules.sh
现在,这非常适合以下用法:1)如果我提交作业并且我的作业脚本使用module load softwareX
,那么没问题,该作业运行得很好。2)如果我在命令行上进行互动工作,并且我键入module load softwareX
,则将软件的路径加载到我的$PATH
中,一切都很好。
但是,这对以下情况不起作用:如果我制作一个简单的bash脚本,该脚本包含行module load softwareX
,当bash脚本执行时,我会遇到错误。例如,这是我的bash脚本:
#!/usr/bin/env bash
echo $PATH
module load softwareX
echo $PATH
当我执行此操作时,我会收到错误 script.sh: line 3L module: command not found
...和$PATH
永远不会改变。有人知道我如何解决这个问题在这三种情况下工作吗?感谢您的帮助!
bash脚本不会调用您的启动文件。您必须明确地做。
请参阅http://www.gnu.org/software/bash/manual/bashref.html#bash-startup-files
调用非交互性
当bash非交互启动时,运行一个shell脚本,例如,它在环境中寻找变量bash_env,如果它出现在那里,则将其值扩展,并使用扩展的值作为文件的名称到阅读并执行。bash的行为好像执行以下命令:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
但是路径变量的值不用于搜索文件名。
如上所述,如果使用 - login选项调用非相互作用的外壳,则Bash尝试从登录Shell启动文件读取和执行命令。
创建子壳时,您会创建一个新的环境。当您退回现有外壳时,您将失去该环境。
我怀疑这是您的模块函数调用的情况。如果将echo $PATH
添加到模块函数的底部,您是否会在功能中看到路径会更改,但是在离开功能时会再次更改?如果是这样,问题是一个子壳问题:
您应该做的是让模块功能打印出新路径,然后执行此操作:
PATH=$(module load softwareX)