bash 如何在 unix 中设置“模块”命令以将软件包添加到 $PATH?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21630779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 09:30:02  来源:igfitidea点击:

How to setup a "module" command in unix to add software package to $PATH?

bashshellmodule

提问by jake9115

I use a lot of computing clusters and these often use a module system for making software packages available. Basically, you use the module command like module load sample_softwareand the sample_softwarepath is added to $PATH. On a cluster, this command can be invoked during interactive usage and job submission usage.

我使用了很多计算集群,这些集群通常使用模块系统来提供软件包。基本上,您使用像这样的模块命令module load sample_software并将sample_software路径添加到$PATH. 在集群上,可以在交互使用和作业提交使用期间调用此命令。

I have a linux box with PBS/Torque queueing system installed so that I can sandbox software for later use on clusters. I need a very similar module system on this box. I started by making a file called modules.shin my `/etc/profile.d/ directory that looks like this:

我有一个安装了 PBS/Torque 排队系统的 linux 盒子,以便我可以沙盒软件供以后在集群上使用。我需要在这个盒子上有一个非常相似的模块系统。我首先modules.sh在我的 `/etc/profile.d/ 目录中创建一个文件,如下所示:

module()
{
if [  == "softwareX" ]; then
    PATH=$PATH:/home/me/dir/softwareX
    export PATH
fi
}

I then put the following line in my .bash_profilescript:

然后我将以下行放入我的.bash_profile脚本中:

source /etc/profile.d/modules.sh

Now, this works great for the following usages: 1) If I submit a job and my job script uses module load softwareX, no problem, the job runs perfectly. 2) If I am working interactively on the command line and I type module load softwareX, then the path to softwareX is loaded into my $PATHand everything works great.

现在,这适用于以下用途:1)如果我提交作业并且我的作业脚本使用module load softwareX,没问题,作业运行完美。2) 如果我在命令行上以交互方式工作并输入module load softwareX,则 softwareX 的路径将加载到我的中,$PATH并且一切正常。

However, this doesn't work for the following situation: If I make a simple bash script that contains the line module load softwareX, when the bash script executes I get an error. For example, here is my bash script:

但是,这不适用于以下情况:如果我制作了一个包含 line 的简单 bash 脚本module load softwareX,则当 bash 脚本执行时,我会收到错误消息。例如,这是我的 bash 脚本:

#!/usr/bin/env bash
echo $PATH
module load softwareX
echo $PATH

When I execute this I receive the error script.sh: line 3L module: command not found

当我执行这个我收到错误 script.sh: line 3L module: command not found

...and the $PATHnever changes. Does anyone know how I can solve this problem to work in all three situations? Thanks for any help!

......而且$PATH永远不会改变。有谁知道我如何解决这个问题以在所有三种情况下工作?谢谢你的帮助!

回答by David W.

When you create a sub-shell, you create a new environment. When you exit back to your existing shell, you lose that environment.

创建子外壳时,您创建了一个新环境。当您退出回现有的 shell 时,您就失去了那个环境。

I suspect this is what is going on with your module function call. If you added echo $PATHto the bottom of your module function, do you see the PATH get changed while inside the function, but changes again when you leave the function? If so, the problem is a sub-shell issue:

我怀疑这就是您的模块函数调用发生的情况。如果您添加echo $PATH到模块函数的底部,您是否看到 PATH 在函数内部时发生了变化,但在您离开该函数时又发生了变化?如果是这样,则问题是子外壳问题:

What you SHOULD do is have your module function print out the new path, and then do this:

您应该做的是让您的模块函数打印出新路径,然后执行以下操作:

PATH=$(module load softwareX)

回答by glenn Hymanman

A bash script won't invoke your startup files. You have to do that explicitly.

bash 脚本不会调用您的启动文件。你必须明确地这样做。

See http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files

请参阅http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files

Invoked non-interactively

When Bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed:

   if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

but the value of the PATH variable is not used to search for the file name.

As noted above, if a non-interactive shell is invoked with the --login option, Bash attempts to read and execute commands from the login shell startup files.

非交互式调用

Bash非交互启动时,为了运行一个shell脚本,例如在环境中寻找变量BASH_ENV,如果出现就将其值展开,并将展开后的值作为文件名进行读取和执行. Bash 的行为就像执行了以下命令:

   if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

但 PATH 变量的值不用于搜索文件名。

如上所述,如果使用 --login 选项调用非交互式 shell,Bash 会尝试从登录 shell 启动文件中读取和执行命令。