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.