There is a bug (or possibly multiple related bugs) in Yosemite with respect to environment variables. When a program is launched in Finder by double-clicking, it will inherit a default set of environment variables from its parent process (I believe this is
launchd currently, but that's not relevant).
GUI programs do not inherit variables from
~/.bashrc or other shell init files.
TeX Live Utility allows the user to add TeX binaries to its internal (i.e., in-memory)
PATH variable by means of a preference setting. Other programs may do via shell scripts, config files in the home directory, or other configuration mechanisms.
Traditionally, UNIX programs store environment variables in the global variable
environ(7) (to see documentation, type
man 7 environ in Terminal). Values in this C-array are generally changed with calls such as
setenv(3) and read with
getenv(3). Child processes launched with
execv(3) will inherit the parent's
environ variable, although some variants such as
execve(2) allow passing a different set of environment variables.
When you call
setenv("PATH", "/usr/texbin:/usr/bin:/usr/sbin", 1), it should replace the existing
PATH=… value in the environment array. Under Yosemite, it appears to either append another
PATH variable, or fail to modify
environ at all. Consequently, even though
getenv(3) may return a correct value, dereferencing the
environ variable will return something with duplicate values or stale values…in other words, garbage.
For TeX Live Utility, the workaround was to launch it from the Terminal as follows:
/Applications/TeX/TeX\ Live\ Utility.app/Contents/MacOS/TeX\ Live\ Utility
Note the backslashes to protect spaces in the program name; this is the actual binary, which resides inside the
.app bundle. The same thing should work for other GUI programs, so please add a comment if it does or does not.
- This workaround may only work with the
- This workaround will certainly only work if
echo $PATH contains the path to your TeX binaries (for MacTeX, this is
- If you're writing code, it appears that
environ(7) is unusable now, and you need to build your own environment and pass it to
This is clearly a bug, and Apple needs to fix this problem in Yosemite. TeX Live Utility 1.19 has a workaround that does not require launching from the Terminal, so I've used it here for illustrative purposes only. The Cocoa
NSProcessInfo object can be used to get a seemingly correct environment, which can be modified and passed to
NSTask. Note that
NSProcessInfo is not thread-safe on all versions of OS X, and this workaround relies on Cocoa picking the "correct" environment variable.
Alternate workarounds may involve using
launchctl to set environment variables. I do not recommend setting this up as a default except as a last resort; it modifies the environment for all programs you run, and can cause problems that are extremely difficult to debug in future (as Mac OS X's
~/.MacOSX/environment.plist used to do).
Inspired by @JoeCheng in the comments, I also wrote a plain C workaround, in the diff here. This should be a lowest-common-denominator for OS X.
More details and a link to an example Cocoa program to test this can be found here. Related problems can be found under the RStudio and Sublime-Text tags.
Any Cocoa program that uses
NSTask (a wrapper object for
fork/exec) to launch a shell or other script appears to be affected. This includes Python, for instance; the problem isn't limited to the C/Objective-C language, as far as I can tell. The problem was extremely difficult to debug as things work correctly when you launch from a debugger in Terminal, or launch under the debugger in Xcode. If I have made wrong inferences, that is a likely cause!
I filed a bug report with Apple, two months before Yosemite was released. The only feedback was a request that I describe how what I was seeing was unexpected. I'll update this if I hear anything further.