On my macOS Sierra 10.12.6, I have my ~/.bash_profile
as shown below.
macbookpro:~ lone$ echo $TERM_PROGRAM
Apple_Terminal
macbookpro:~ lone$ cat ~/.bash_profile
echo 1: PATH: $PATH
PATH=BEG:$PATH:END
echo 2: PATH: $PATH
I do not have ~/.bashrc
or ~/.profile
.
macbookpro:~ lone$ ls -ld ~/.bash*
-rw------- 1 lone CORP\Domain Users 6875 Jan 12 19:05 /Users/lone/.bash_history
-rw-r--r-- 1 lone CORP\Domain Users 59 Jan 12 19:05 /Users/lone/.bash_profile
drwx------ 3 lone CORP\Domain Users 102 Jan 12 19:06 /Users/lone/.bash_sessions
macbookpro:~ lone$ ls -l ~/.profile
ls: /Users/lone/.profile: No such file or directory
When I launch a new terminal, I get this output, which is expected.
Last login: Fri Jan 12 11:02:56 on ttys000
1: PATH: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
2: PATH: BEG:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:END
macbookpro:~ lone$ rm -rf ~/.bash_sessions/
Now if I run tmux in this terminal, I get this output, in the tmux pane after it starts.
1: PATH: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:BEG:END
2: PATH: BEG:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:BEG:END:END
macbookpro:~ lone$
Why does the first line show BEG:END
in the end? I was expecting it to have BEG
in the beginning and END
in the end just like in the case of launching a terminal.
I believe I have found the answer. The /etc/profile
file looks like this.
# System-wide .profile for sh(1)
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
if [ "${BASH-no}" != "no" ]; then
[ -r /etc/bashrc ] && . /etc/bashrc
fi
The clue is this command invocation in this startup file.
/usr/libexec/path_helper -s
Let me remove ~/.bash_profile
and simulate the startup sequence.
macbookpro:~ lone$ rm ~/.bash_profile
macbookpro:~ lone$ cat /etc/paths
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
macbookpro:~ lone$ ls /etc/paths.d/
macbookpro:~ lone$ /usr/libexec/path_helper -s
PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"; export PATH;
So what we see so far is that path_helper
takes the paths in /etc/paths
and returns a path string that /etc/profile
takes and eval
uates to define the PATH
variable.
Let us see what happens when we have redefined PATH
variable to BEG:$PATH:END
ourselves (to simulate we had done earlier in ~/.bash_profile
).
macbookpro:~ lone$ PATH=BEG:$PATH:END
macbookpro:~ lone$ echo $PATH
BEG:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:END
macbookpro:~ lone$ /usr/libexec/path_helper -s
PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:BEG:END"; export PATH;
So path_helper
appears to construct the PATH
in the following manner:
Pick all paths from /etc/paths
.
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
Append the current PATH
.
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:BEG:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:END
Cleanup the PATH
by removing duplicates.
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:BEG::END