Repository: ESMCI/cime

Issue:
"source" not available in all systems

env_mach_specific.py has this line:
`source_cmd = "source {} && ".format(init_path)`

Turns out "source" is not available in Ubuntu.  Most systems link "/bin/sh" to bash but Ubuntu links it to "dash" which is faster and does not define the "source" command.

Solution is to use "." which is POSIX-standard command for executing commands from a file.
`source_cmd = ". {} && ".format(init_path)`

Thanks to @dqwu who found this and the solution.



Discussion:
Grepping the CCS for "source" is fun but I don't think there's anywhere else this is used.
@rljacob I'll make this update and double check it's not needed anywhere else.
I think I saw @sarich push a branch with some fixes.
Nevermind, that was part of some other development.  Go ahead @jasonb5 

Resolving patch:
diff --git a/CIME/XML/env_mach_specific.py b/CIME/XML/env_mach_specific.py
--- a/CIME/XML/env_mach_specific.py
+++ b/CIME/XML/env_mach_specific.py
@@ -184,7 +184,7 @@ def list_modules(self):
         # setup script if it exists.
         init_path = self.get_module_system_init_path("sh")
         if init_path:
-            source_cmd = "source {} && ".format(init_path)
+            source_cmd = ". {} && ".format(init_path)
         else:
             source_cmd = ""
 
@@ -231,6 +231,7 @@ def make_env_mach_specific_file(self, shell, case, output_dir=""):
         case: case object
         output_dir: string - path to output directory (if empty string, uses current directory)
         """
+        source_cmd = "." if shell == "sh" else "source"
         module_system = self.get_module_system_type()
         sh_init_cmd = self.get_module_system_init_path(shell)
         sh_mod_cmd = self.get_module_system_cmd_path(shell)
@@ -244,12 +245,12 @@ def make_env_mach_specific_file(self, shell, case, output_dir=""):
         )
         lines.append("# Run ./case.setup --reset to regenerate this file")
         if sh_init_cmd:
-            lines.append("source {}".format(sh_init_cmd))
+            lines.append("{} {}".format(source_cmd, sh_init_cmd))
 
         if "SOFTENV_ALIASES" in os.environ:
-            lines.append("source $SOFTENV_ALIASES")
+            lines.append("{} $SOFTENV_ALIASES".format(source_cmd))
         if "SOFTENV_LOAD" in os.environ:
-            lines.append("source $SOFTENV_LOAD")
+            lines.append("{} $SOFTENV_LOAD".format(source_cmd))
 
         if self._unit_testing or self._standalone_configure:
             job = None
@@ -469,12 +470,12 @@ def _load_modules_generic(self, modules_to_load, verbose=False):
         # do by running shell command and looking at the changes
         # in the environment.
 
-        cmd = "source {}".format(sh_init_cmd)
+        cmd = ". {}".format(sh_init_cmd)
 
         if "SOFTENV_ALIASES" in os.environ:
-            cmd += " && source $SOFTENV_ALIASES"
+            cmd += " && . $SOFTENV_ALIASES"
         if "SOFTENV_LOAD" in os.environ:
-            cmd += " && source $SOFTENV_LOAD"
+            cmd += " && . $SOFTENV_LOAD"
 
         for action, argument in modules_to_load:
             cmd += " && {} {} {}".format(
@@ -538,7 +539,8 @@ def _mach_specific_header(self, shell):
 """.format(
             shell
         )
-        header += "source {}".format(self.get_module_system_init_path(shell))
+        source_cmd = "." if shell == "sh" else "source"
+        header += "{} {}".format(source_cmd, self.get_module_system_init_path(shell))
         return header
 
     def get_module_system_type(self):


Test patch: