我使用了大量的计算集群,这些集群通常使用模块系统来提供软件包。基本上,您使用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
,那么softwareX的路径将加载到我的$PATH
中,一切正常。
但是,这不适用于以下情况:如果我创建一个包含行module load softwareX
的简单bash脚本,则在执行bash脚本时会出现错误。例如,这是我的bash脚本:
#!/usr/bin/env bash
echo $PATH
module load softwareX
echo $PATH
执行此操作时,我收到错误script.sh: line 3L module: command not found
... $PATH
永远不会改变。有谁知道如何在这三种情况下解决这个问题?谢谢你的帮助!
答案 0 :(得分:1)
创建子shell时,可以创建新环境。当您退回到现有的shell时,会丢失该环境。
我怀疑这是你的模块函数调用正在发生的事情。如果您将echo $PATH
添加到模块函数的底部,您是否看到PATH在函数内部被更改,但是当您离开函数时会再次更改?如果是这样,问题是子shell问题:
你应该做的是让你的模块功能打印出新的路径,然后这样做:
PATH=$(module load softwareX)
答案 1 :(得分:1)
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
但PATH变量的值不用于搜索文件名。
如上所述,如果使用--login选项调用非交互式shell,Bash会尝试从登录shell启动文件中读取和执行命令。