Background
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 ~/.bash_profile, ~/.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.
Problem
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 fork(2) and 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.
Workaround
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.
Caveats
- This workaround may only work with the
bash shell
- This workaround will certainly only work if
echo $PATH contains the path to your TeX binaries (for MacTeX, this is /usr/texbin)
- 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 execve(2) or execle(3)
Alternatives
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.
Additional
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.
char **environis part of POSIX, it's hard to see how they'd claim it's not a bug. Enforcing anexecafterforkis the only recent issue I recall in this regard, but at least that had been documented for years beforehand. – Adam Maxwell Oct 22 '14 at 22:42