我使用哪个 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
我正在从事各种需要特定编译器的项目。幸运的是,在我正在使用的机器上,我得到了一个命令 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