env-shell.sh

Unix shells read a variety of config files (/etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profile, and ~/.bashrc) at various times depending on how they are invoked, whether they are login shells or interactive shells or both, etc. This stuff can be confusing to the beginner. This document explains how to set things up in a hopefully straightforward way.

What env-shell.sh does

The correct shell environment corresponding to a workspace is generated by cmake and written to $I3_BUILD/env-shell.sh. This script contains the correct settings for PATH, LD_LIBRARY_PATH, PYTHONPATH and so forth. The correct settings depend on which tools are available in your toolset, which metaproject and version you are running, etc.

Executing this script at the command line will spawn a subshell with the appropriate environment:

% ./env-shell.sh
************************************************************************
*                                                                      *
*                   W E L C O M E  to  I C E T R A Y                   *
*                                                                      *
*                   Version combo.stable    r171557                    *
*                                                                      *
*                You are welcome to visit our Web site                 *
*                        http://icecube.umd.edu                        *
*                                                                      *
************************************************************************

Icetray environment has:
   I3_SRC       = /home/olivas/icecube/combo/stable/src
   I3_BUILD     = /home/olivas/icecube/combo/stable/build
   I3_TESTDATA  = /home/olivas/icecube/test-data/releases/V00-00-01
   Python       = 2.7.15rc1

Under the hood there are many other environment variables set. You can look at the file to see exactly what. To unload this environment, simply exit the subshell:

% exit
Exited Icetray Environment.
%

Because this script executes a subshell and is responsible for setting certain environment variables, misconfigured shell initialization files (.bashrc and the like) can spoil the party by overwriting the intended settings. For example, the env-shell.sh should prepend the environment variable PATH with $I3_BUILD/bin. The correct behavior would look something like this:

% echo $PATH
/usr/bin:/bin
% ./env-shell.sh
************************************************************************
*                                                                      *
*                   W E L C O M E  to  I C E T R A Y                   *
*                                                                      *
*                   Version combo.stable    r171557                    *
*                                                                      *
*                You are welcome to visit our Web site                 *
*                        http://icecube.umd.edu                        *
*                                                                      *
************************************************************************

Icetray environment has:
   I3_SRC       = /home/olivas/icecube/combo/stable/src
   I3_BUILD     = /home/olivas/icecube/combo/stable/build
   I3_TESTDATA  = /home/olivas/icecube/test-data/releases/V00-00-01
   Python       = 2.7.15rc1
% echo $PATH
/home/olivas/icecube/combo/stable/build/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

You can see that also the path to the ROOT installation in the toolset has been added. If I erroneously assign to PATH in my .bashrc, ie if .bashrc contains the following line:

PATH=/path/to/my/stuff

then the desired settings will be overwritten by my subshell as it initializes:

% echo $PATH
/usr/bin:/bin
% ./env-shell.sh
************************************************************************
*                                                                      *
*                   W E L C O M E  to  I C E T R A Y                   *
*                                                                      *
*                   Version combo.stable    r171557                    *
*                                                                      *
*                You are welcome to visit our Web site                 *
*                        http://icecube.umd.edu                        *
*                                                                      *
************************************************************************

Icetray environment has:
   I3_SRC       = /home/olivas/icecube/combo/stable/src
   I3_BUILD     = /home/olivas/icecube/combo/stable/build
   I3_TESTDATA  = /home/olivas/icecube/test-data/releases/V00-00-01
   Python       = 2.7.15rc1
% echo $PATH
/usr/bin:/bin

A good way to set up your shell

Assume you have a ROOT installation in a special location; in order to use it you need to set ROOTSYS, LD_LIBRARY_PATH and PATH.

Warning

You don’t want to actually mix root versions like this. This is almost guaranteed to cause subtle errors that manifest themselves in bizarre ways. Root here just means “some tool that I’ve had to set up myself”.

As explained, if you simply modify these variables in your .bashrc, you’ll have problems later on. There are a few ways to handle this:

If-then blocks

In the initialization files you could put the assignments to these variables inside an if-then block so that they are executed only once. Here it is .bashrc or .zshrc -style:

#
# if MY_ENV_SET_ALREADY has zero length,
#
if [ -z "$MY_ENV_SET_ALREADY" ]; then

   #
   #  set my variables
   #
   export PATH=/path/to/my/root/bin:$PATH
   export ROOTSYS=/path/to/my/root

   #
   #  set the flag that we shouldn't do this in the future
   #
   export MY_ENV_SET_ALREADY=true
fi

So the block that sets PATH and ROOTSYS will execute only on the first spawn of a subshell.

You should be able to get the same effect with .tcsh, (though I personally wouldn’t try). Have a look at https://www.grymoire.com/Unix/CshTop10.txt and http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/ .

Shell functions

If you have a complicated environment or lots of tools, you may want to put the settings into shell functions that you can run when you need to use particular tools (again, this in .bashrc):

use_root518() {
  echo "Setting environment for root 5.18"
  export ROOTSYS=/path/to/my/root-5.18.00
  export PATH=$ROOTSYS/bin:$PATH
  export LD_LIBRARY_PATH=$ROOTSYS/lib:$LD_LIBRARY_PATH
}

use_root520() {
  echo "Setting environment for root 5.20"
  export ROOTSYS=/path/to/my/root-5.20.00
  export PATH=$ROOTSYS/bin:$PATH
  export LD_LIBRARY_PATH=$ROOTSYS/lib:$LD_LIBRARY_PATH
}

Your default shell will have none of this special stuff loaded, but you can configure things easily:

$ echo $PATH
/usr/bin
$ use_root520
Setting environment for root 5.20
$ echo $PATH
/path/to/my/root-5.20.00/bin:/usr/bin

Warning

Again: you don’t want to try to override the ROOT that a metaproject is built against like this. This is almost guaranteed to cause subtle errors that manifest themselves in bizarre ways. Root here just means “some tool that I’ve had to set up myself”.

Refer to your shell’s man page for further detail regarding shell invocation and initialisation (section “INVOCATION” for bash, section “STARTUP/SHUTDOWN FILES” for zsh).