Source shell script in modulefile¶
When working with large software suite providing a shell script for their
enablement in user environment, it is usually desired to also provide access
to these software through module. However these software enablement may be
complex and it may be wise to keep using the shell script provided by software
editor rather crafting a modulefile from scratch.
This recipe describes how to make modulefiles for such software by using the enablement shell script provided with them.
Implementation¶
Modules version 4.6 introduces a new sub-command named sh-to-mod and
a new modulefile command named source-sh. The sh-to-mod
outputs as a modulefile content the environment changes done by the evaluation
of a shell script passed as argument. On the other hand, the source-sh
modulefile command sources environment changes done by the evaluation of a
shell script passed as argument.
Both new features relies on the same mechanism that starts a designated shell to:
- get current environment state (environment variables, shell aliases, shell functions and current working directory)
- source designated shell script with defined arguments
- get resulting environment state
Once done, environment prior and after script source are compared to determine
the corresponding environment changes and translate those changes into
modulefile commands (setenv, prepend-path,
set-alias, set-function, ...).
sh-to-mod outputs these resulting modulefile commands. This output
can be redirected into a file to create a modulefile. source-sh on
the other hand sources the resulting modulefile commands to evaluate them as
if they were written in the modulefile calling source-sh.
sh-to-mod and source-sh support the following shells: sh, dash,
csh, tcsh, bash, ksh, ksh93, zsh and fish.
Compatible with Modules v4.6+
Usage example¶
For this recipe, a dummy software named foo is used as example. foo is
installed in version 1.2 in example/source-script-in-modulefile/foo-1.2
directory and it provides a foo-setup.sh script to activate itself in
user environment:
#!/bin/bash
export FOOENV="$1"
export PATH=$(dirname $BASH_SOURCE)/bin:$PATH
alias foo='foobin -q -l'
First line of foo-setup.sh script helps to identify which shell needs to
be used to evaluate it: bash.
sh-to-mod may be used to get this script translated as a
modulefile:
$ module sh-to-mod bash example/source-script-in-modulefile/foo-1.2/foo-setup.sh arg1
#%Module
prepend-path PATH example/source-script-in-modulefile/foo-1.2/bin
set-alias foo {foobin -q -l}
setenv FOOENV arg1
Output could be redirected into a foo/1.2 file and make it the modulefile
to enable software foo:
$ mkdir -p modulefiles/foo
$ module sh-to-mod bash example/source-script-in-modulefile/foo-1.2/foo-setup.sh arg1 >modulefiles/foo/1.2
$ module use ./modulefiles
$ module show foo
-------------------------------------------------------------------
modulefiles/foo/1.2:
prepend-path PATH example/source-script-in-modulefile/foo-1.2/bin
set-alias foo {foobin -q -l}
setenv FOOENV arg1
-------------------------------------------------------------------
Instead of transforming shell script in modulefile, a modulefile using
source-sh modulefile command to evaluate shell script at modulefile
evaluation time may be written:
$ cat <<EOF >modulefiles/foo/1.2
#%Module4.6
source-sh bash example/source-script-in-modulefile/foo-1.2/foo-setup.sh arg1
EOF
When displaying a modulefile using source-sh modulefile command,
modulefile commands resulting from source-sh evaluation are reported:
$ module show foo/1.2
-------------------------------------------------------------------
modulefiles/foo/1.2:
prepend-path PATH example/source-script-in-modulefile/foo-1.2/bin
set-alias foo {foobin -q -l}
setenv FOOENV arg1
-------------------------------------------------------------------
Loading this foo/1.2 module will enable access to software foo:
$ module load foo/1.2
$ alias foo
alias foo='foobin -q -l'
$ foo
foo, version 1.2
Unloading foo/1.2 module will properly revert these environment settings:
$ module unload foo/1.2
$ alias foo
bash: alias: foo: not found
$ foobin
bash: foobin: command not found
As conclusion, these new features enable to leverage the setup scripts that
are provided along with software to make them reachable from the module
environment.