diff --git a/doc/binary_c2.lyx b/doc/binary_c2.lyx
index 34422bf7b5854797713e85635dba81c1a9a72e74..071ab0fc31f26a543e092db4d3c7df1b0fb138be 100644
--- a/doc/binary_c2.lyx
+++ b/doc/binary_c2.lyx
@@ -1434,7 +1434,7 @@ status open
 
 \begin_layout Plain Layout
 
-export LD_LIBRARY_PATH=$HOME/lib
+export LD_LIBRARY_PATH=$HOME/lib:$BINARY_C/src
 \end_layout
 
 \begin_layout Plain Layout
@@ -12299,6 +12299,59 @@ filename "binary_grid2.lyx"
 \end_inset
 
 
+\end_layout
+
+\begin_layout Section
+Making populations of stars with 
+\begin_inset Formula $\binarycpython$
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:Running-a-grid-python"
+
+\end_inset
+
+Please see instructions at 
+\end_layout
+
+\begin_layout Itemize
+\begin_inset Flex URL
+status open
+
+\begin_layout Plain Layout
+
+https://gitlab.eps.surrey.ac.uk/ri0005/binary_c-python
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Itemize
+\begin_inset Flex URL
+status open
+
+\begin_layout Plain Layout
+
+https://pypi.org/project/binarycpython/
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset Newpage pagebreak
+\end_inset
+
+
 \end_layout
 
 \begin_layout Section
diff --git a/doc/binary_grid2.lyx b/doc/binary_grid2.lyx
index 5f5e8e93d5636ca725a816865132c8c6cae2648d..9cb20a254747ad49ecbcee51b5f20d5fe0c40c20 100644
--- a/doc/binary_grid2.lyx
+++ b/doc/binary_grid2.lyx
@@ -2826,7 +2826,11 @@ grid script
 \emph default
 and coupling your population synthesis to 
 \emph on
-binary_c/nucsyn
+
+\begin_inset Formula $\binaryc$
+\end_inset
+
+
 \end_layout
 
 \begin_layout Standard
@@ -2911,7 +2915,121 @@ xxx
 \end_inset
 
 
-\begin_inset Newline newline
+\end_layout
+
+\begin_layout Subsubsection
+Loading the 
+\begin_inset Formula $\binaryc$
+\end_inset
+
+ library 
+\end_layout
+
+\begin_layout Standard
+When using 
+\begin_inset Formula $\binarygrid$
+\end_inset
+
+ you need to ensure the binary_c shared library is loaded.
+ Usually, this means you have to set the environment variable 
+\begin_inset Flex Envvar
+status open
+
+\begin_layout Plain Layout
+LD_LIBRARY_PATH
+\end_layout
+
+\end_inset
+
+ (or 
+\begin_inset Flex Envvar
+status open
+
+\begin_layout Plain Layout
+DYLD_LIBRARY_PATH
+\end_layout
+
+\end_inset
+
+ on 
+\begin_inset Flex OS
+status open
+
+\begin_layout Plain Layout
+OSX
+\end_layout
+
+\end_inset
+
+) to point to the location where the library is installed, usually 
+\begin_inset Flex File
+status open
+
+\begin_layout Plain Layout
+$BINARY_C/src
+\end_layout
+
+\end_inset
+
+.
+ If this fails to work, try the following using 
+\begin_inset Flex Envvar
+status open
+
+\begin_layout Plain Layout
+LD_PRELOAD
+\end_layout
+
+\end_inset
+
+ (or 
+\begin_inset Flex Envvar
+status open
+
+\begin_layout Plain Layout
+DYLD_PRELOAD
+\end_layout
+
+\end_inset
+
+ on 
+\begin_inset Flex OS
+status open
+
+\begin_layout Plain Layout
+OSX
+\end_layout
+
+\end_inset
+
+, see Sec.
+\begin_inset space ~
+\end_inset
+
+
+\begin_inset CommandInset ref
+LatexCommand ref
+reference "subsec:binaryc-on-MacOSX"
+plural "false"
+caps "false"
+noprefix "false"
+
+\end_inset
+
+ for Mac-specific instructions) from in the 
+\begin_inset Formula $\binaryc$
+\end_inset
+
+ directory:
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+LD_PRELOAD=./src/libbinary_c.so <script>
+\end_layout
+
 \end_inset
 
 
@@ -2920,7 +3038,11 @@ xxx
 \begin_layout Subsubsection
 Logging in 
 \emph on
-binary_c
+
+\begin_inset Formula $\binaryc$
+\end_inset
+
+
 \end_layout
 
 \begin_layout Standard
diff --git a/src/binary_c_code_options.h b/src/binary_c_code_options.h
index 4ba20472806dc4996293980237739e00304f15d5..b7872869294d3ad213643d1ad2b135c9d1e274ea 100644
--- a/src/binary_c_code_options.h
+++ b/src/binary_c_code_options.h
@@ -1225,4 +1225,13 @@ void Print_trace(void);
 #define Fallthrough /* do nothing */
 #endif
 
+/*
+ * If USE_SPLIT_COMMANDLINE is TRUE, we used
+ * split_commandline, which calls wordexp(), to
+ * analyse command-line strings. This performs
+ * shell expansion, so is slow, and is usually
+ * not required.
+ */
+//#define USE_SPLIT_COMMANDLINE
+
 #endif //BINARY_C_CODE_OPTIONS_H
diff --git a/src/setup/new_system.c b/src/setup/new_system.c
index 352bd780cb0366fb1fe97de08e4f0a9e428a3db6..15af72e48c8fffaad3d0078efd6256e60b4b18e6 100644
--- a/src/setup/new_system.c
+++ b/src/setup/new_system.c
@@ -83,30 +83,35 @@ void new_system(struct stardata_t ** new_stardata,
         /*
          * Split given arg string
          */
-        //char ** const argv_system = split_commandline(*argv,&argc_system);
-        size_t argc_system_size;
         int argc_system;
+#ifdef USE_SPLIT_COMMANDLINE
+        char ** const argv_system = split_commandline(*argv,&argc_system);
+#else
+
+        size_t alloced;
         char ** argv_system = NULL;
         char * argvc = *argv;
-
-        string_split(argvc,
-                     &argv_system,
-                     ' ',
-                     1024,
-                     &argc_system_size,
-                     TRUE);
-        argc_system = (int)argc_system_size;
+        argc_system = (int)string_split(argvc,
+                                        &argv_system,
+                                        ' ',
+                                        1024,
+                                        &alloced,
+                                        TRUE);
         if(argv_system==NULL)
         {
             Exit_binary_c_no_stardata(BINARY_C_WRONG_ARGUMENT,
                                       "Command line split failed: argv_system==NULL from command line string \"%s\"\n",*argv);
         }
+#endif // USE_SPLIT_COMMANDLINE
         parse_arguments(1,
                         argc_system,
                         argv_system,
                         *new_stardata);
-        //split_commandline_free(argv_system,argc_system);
+#ifdef USE_SPLIT_COMMANDLINE
+        split_commandline_free(argv_system,argc_system);
+#else
         Safe_free(argv_system);
+#endif
         dprint(*new_stardata,"scanned %d args\n",argc_system);
     }
     else if(argc>=0)
diff --git a/src/setup/parse_arguments_from_string.c b/src/setup/parse_arguments_from_string.c
index 0fd3c02187da021358246e3a0242c76940e8c5c9..5eb047f775d3615b2647de198c24ae7157a78771 100644
--- a/src/setup/parse_arguments_from_string.c
+++ b/src/setup/parse_arguments_from_string.c
@@ -8,12 +8,29 @@ void parse_arguments_from_string(const char * RESTRICT const argstring,
 {
 
     /*
-     * Split the string into the argv and argc arrays, then 
+     * Split the string into the argv and argc arrays, then
      * free the memory in those arrays.
      */
+    char ** argv = NULL;
     Dprint("split string into args\n");
-    char ** argv = split_commandline(argstring, argc);
+#ifdef USE_SPLIT_COMMANDLINE
+    /*
+     * This is slower, but performs shell expansion
+     */
+    argv = split_commandline(argstring, argc);
     Dprint("parse %d args from split string\n",*argc);
     parse_arguments(1,*argc,argv,stardata);
     split_commandline_free(argv,*argc);
+#else
+    size_t alloced;
+    *argc = (int)string_split_preserve(argstring,
+                                       &argv,
+                                       ' ',
+                                       1024,
+                                       &alloced,
+                                       TRUE);
+    Dprint("parse %d args from split string\n",*argc);
+    parse_arguments(1,*argc,argv,stardata);
+    Safe_free(argv);
+#endif
 }
diff --git a/src/setup/version.c b/src/setup/version.c
index 4fb360fe3fe3ea37b920983e2b7c14f0bad533c8..33649ba1d374359895e55de81ec641a197172c59 100644
--- a/src/setup/version.c
+++ b/src/setup/version.c
@@ -1133,6 +1133,7 @@ void version(struct stardata_t * RESTRICT const stardata)
     Macrotest(__APPLE__);
     Macrotest(__arm__);
     Macrotest(__i386__);
+    Macrotest(USE_SPLIT_COMMANDLINE);
 #ifdef ALIGNSIZE
     Printf("Memory is aligned to %d bytes (set in ALIGNSIZE)\n",ALIGNSIZE);
 #else
diff --git a/src/string/string_prototypes.h b/src/string/string_prototypes.h
index 95ae67e0c97e8df009bae4eb17bd6cda259d9ad3..a4a65e48d5fa5d0670ab40fd03c5f651ee0f6e9b 100644
--- a/src/string/string_prototypes.h
+++ b/src/string/string_prototypes.h
@@ -35,7 +35,12 @@ size_t string_split(const char * const RESTRICT string,
                     const size_t prealloc,
                     size_t * const alloced,
                     const Boolean shrink);
-
+size_t string_split_preserve(const char * const RESTRICT string,
+                             char *** const RESTRICT array,
+                             const char delimiter,
+                             const size_t prealloc,
+                             size_t * const alloced,
+                             const Boolean shrink);
 
 int strtoi(const char * const RESTRICT s, char **endptr, const int base);
 short int strtoshort(const char * const RESTRICT s, char **endptr, const int base);
diff --git a/src/string/string_split.c b/src/string/string_split.c
index 1870a6eeee54d47fd0f47a3c11fe3b63783b9d82..b72b5333dd57b788153d57c0afb2dae8c373d4f7 100644
--- a/src/string/string_split.c
+++ b/src/string/string_split.c
@@ -18,6 +18,10 @@ No_empty_translation_unit_warning;
  * You can even use prealloc to maintain the size of *array passed
  * in, if it's alloc'd once, and the alloc size never changes,
  * you never have to make it again.
+ *
+ * Because we use strtok_r, the string passed in is modified.
+ * If you do not want to modify the string, use string_split_preserve()
+ * instead.
  */
 
 
diff --git a/src/string/string_split_preserve.c b/src/string/string_split_preserve.c
new file mode 100644
index 0000000000000000000000000000000000000000..13f516fae447ea521851adc27b6f1d885ac8fc50
--- /dev/null
+++ b/src/string/string_split_preserve.c
@@ -0,0 +1,33 @@
+#include "../binary_c.h"
+No_empty_translation_unit_warning;
+
+size_t string_split_preserve(const char * const RESTRICT string,
+                             char *** const RESTRICT array,
+                             const char delimiter,
+                             const size_t prealloc,
+                             size_t * const alloced,
+                             const Boolean shrink)
+{
+    /*
+     * Like string_split, but copies the string
+     * passed in and works on the copy, thus does not
+     * change the string.
+     */
+    char * string_copy = strdup(string);
+    size_t s;
+    if(string_copy != NULL)
+    {
+        s = string_split(string_copy,
+                         array,
+                         delimiter,
+                         prealloc,
+                         alloced,
+                         shrink);
+        Safe_free(string_copy);
+    }
+    else
+    {
+        s = 0;
+    }
+    return s;
+}