我使用哪个 UNIX 实用程序?

Which UNIX utility do I use?

我正在从事各种需要特定编译器的项目。幸运的是,在我正在使用的机器上,我得到了一个命令 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 开头的部分(例如 PrgEnv-xxx 用于 xxx 编译器,以当前为准加载),然后执行命令 module swap PrgEnv-xxx PrgEnv-cray 表示一个需要 cray 编译器的项目。

这里的要点是我无法加载 cray 编译器(比如说),除非我 un 加载当前加载的任何编译器。我可以通过检查 module list 的结果来访问此信息,但我宁愿只编写一个脚本来自动执行所有这些操作。

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

#!/bin/bash

[ $# = 1 ] || { echo "Usage: [=10=] PrgEnv-new" >&2; exit 1; }

new_module="${1:?}"

cur_module=$(module list | sed -n '/^[0-9]*) *\(PrgEnv-[a-zA-Z0-9_]*\)\/.*/ s///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 抑制正常的 'echo' 操作。该模式查找数字后跟 ) 和空格以及 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