我应该使用哪种UNIX实用程序



我正在处理各种需要特定编译器的项目。幸运的是,在我工作的机器上,我得到了一个命令module,这使得交换编译器变得很容易,例如

module unload PrgEnv-intel
module load PrgEnv-cray

或者,

module swap PrgEnv-intel PrgEnv-cray

还有一个命令module list,它列出了当前加载的所有模块。输出大致为

Currently loaded modules:
1) module_foo/v2.3
2) module_bar/1.1.8
...
17) PrgEnv-pgi/5.2.40

或者类似的东西。(编译器不一定列在第17位;它只是在列表中的某个位置。)

我的问题是:有多种可能性可以在给定的时间加载编译器。我想在每个项目的目录中写一个脚本,它接受module list的输出,找到列表中以PrgEnv开头的部分(例如,xxx编译器的PrgEnv-xxx,无论当前加载的是哪一个),然后为需要cray编译器的项目执行命令module swap PrgEnv-xxx PrgEnv-cray

这里的重点是,除非我un加载当前加载的编译器,否则我无法加载cray编译器。我可以通过检查module list的结果来访问这些信息,但我宁愿只编写一个自动化所有这些的脚本。

这是疯狂的过度杀戮吗?也许吧,但我目前也在尝试学习如何使用UNIX命令解决更常见的问题,我认为这将是一次很好的学习经历。

#!/bin/bash
[ $# = 1 ] || { echo "Usage: $0 PrgEnv-new" >&2; exit 1; }
new_module="${1:?}"
cur_module=$(module list | sed -n '/^[0-9]*) *(PrgEnv-[a-zA-Z0-9_]*)/.*/ s//1/p')
if [ -z "$cur_module" ]
then module load "$new_module"
else if [ "$cur_module" != "$new_module" ]
then module swap "$cur_module" "$new_module"
else echo "Current module is $cur_module; so is requested module"
fi

它使用标准的(史前的)sed符号,并且应该适用于任何版本。-n抑制正常的"回声"操作。该模式查找后面跟有)和空格的数字和PrgEnv-,以及后面跟着/和垃圾的标识符。它将所有这些替换为PrgEnv-和标识符,并打印生成的行。它可以,也许应该,在那之后退出(将p更改为{ p; q; })。

以下代码测试是否加载了模块。如果没有,则加载新的。如果新模块与当前模块不同,则会交换它们。如果新模块与当前模块相同,它会这么说

第一行检查是否使用一个参数调用了脚本,如果没有,则打印使用消息。第二个捕获参数中的值,检查它是否为空(所以有人没有想到会调用switch_env '',假设脚本名为switch_env)。

module list | cut -d' ' -f2 | cut -d/ -f1 | grep ^PrgEnv | xargs module unload && module load PrgEnv-cray

最新更新