Open Terminal Window with Predefined Environment Variables (Including `PATH`)

Solution 1:

You need to explicitly start an interactive bash shell at the end of your script in order to keep the window open when you open the .command file from Finder.

The following revision of your script demonstrates that and also streamlines other aspects of your code:

#!/bin/bash

# Note: $PATH already exists as an exported variable, assigning to it
#       again preserves that status, so there's no need to call `export` below.

# Adding CMake to Path
PATH+=:/Users/Shared/CMake/CMake.app/Contents/bin/

# Adding Ninja to Path
PATH+=:/Users/Shared/Ninja/

# Adding GCC to Path
PATH+=:/usr/local/gcc-8.2/bin/

cat <<EOF
Path updated to:

  $PATH

Starting interactive Bash shell...
EOF

# Start an interactive Bash shell that inherits this script's environment
# and keeps the window open.
# Using -l makes the interactive shell a login shell, which makes it
# load the same initialization files as shells created by Terminal.app,
# notably, ~/.bash_profile
# Be sure that ~/.bash_profile doesn't override $PATH.
exec bash -l

This .command file will also from an existing terminal window, but note that you will enter an interactive child shell - exiting from that child shell will return to you to the original one.


It is possible to amend your script so that if you invoke it from an existing terminal window (shell), it modifies that shell's environment directly, but you then have to source / . the script on invocation (e.g., . ./script.command):

#!/bin/bash

# Note: $PATH already exists as an exported variable, assigning to it
#       again preserves that status, so there's no need to call `export` below.

# Adding CMake to Path
PATH+=:/Users/Shared/CMake/CMake.app/Contents/bin/

# Adding Ninja to Path
PATH+=:/Users/Shared/Ninja/

# Adding GCC to Path
PATH+=:/usr/local/gcc-8.2/bin/

# Determine if this script is being sourced.
[[ $0 != "$BASH_SOURCE" ]] && sourced=1 || sourced=0

cat <<EOF
Path updated to:

  $PATH

EOF

if (( sourced )); then # sourced from the calling shell.
  # The calling shell's environment has been modified - nothing more to do.
  :
else # otherwise: launched from Finder or from a terminal without sourcing
  # A new interactive shell must be launched for the environment modifications
  # to take effect and, if launched from Finder, to keep the terminal window
  # open.
  echo "Starting new interactive Bash shell with modified environment..."
  # Using -l makes the interactive shell a login shell, which makes it
  # load the same initialization files as shells created by Terminal.app,
  # notably, ~/.bash_profile
  # Be sure that ~/.bash_profile doesn't override $PATH.
  exec bash -l
fi